Issue
I'm trying to validate from an API (Angular's in-memory API) that a user exists given a username. The function checkUsernameExists(username)
returns an Observable<boolean>
based on whether the API returns undefined or a user object. I'm having an issue that regardless of the username (existing or not existing) it always returns false. I know that getUser()
functions correctly as it returns undefined when a user doesn't exists and the user object when it does.
Preferably would only like to adjust the checkUsernameExists
function if possible. This function is used for a (working) async validator. I've looked up all over how to solve this type of thing but can't find anything that isn't deprecated or fits what I need in order for it work properly.
usersUrl = '/api/users';
constructor(private http: HttpClient) {}
users = this.http.get<User[]>(this.usersUrl).pipe(shareReplay());
// gets a user object when subscribed to
getUser(username: string): Observable<User | undefined> {
return this.users.pipe(
take(1),
map((users: User[]) => {
return users.find((user) => user.username === username);
})
);
}
// check if user exists
checkUsernameExists(username: string): Observable<boolean> {
var userValid = false;
this.getUser('dummyuser@dummy.dum')
.pipe(take(1)).subscribe(
result => {
if (result === undefined) {
console.log('result: ', result);
return (userValid = false);
} else {
console.log('result: ', result);
return (userValid = true);
}
}
);
console.log(userValid) // no matter the username, the value is always the same as its initialization (false)
return of(userValid);
}
Solution
your order of operations is the the problem in checkUserNameExists
method
you must wait for the observable to complete. but your code is making call to an observable this.getUser
and then immediately returning return of(userValid)
.
since the observable has not completed, the vale of userValid is stil the default false
. which is the behavior you described
Update your method to
checkUsernameExists(username: string): Observable<boolean> {
return this.getUser('dummyuser@dummy.dum').pipe(
.map( (result: any) => {
if (result === undefined) {
console.log('result: ', result);
return (userValid = false);
} else {
console.log('result: ', result);
return (userValid = true);
}
})
);
}
this ensures that the userValid
is only returned when the observable has completed.
and is also removes the need for double susbscription
Answered By - Edward
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.