Reputation: 892
I can't understand why adding .take(1) at the end of my observable, triggers the result, and if I don't it keeps pending:
function generateToken(identifier){
return new Observable<string>((observer) => {
jwt.sign(identifier, 'devsecret', (err, token) => {
if (err) {
observer.error(err);
} else if (token) {
observer.next(token);
}
});
}).pipe( take(1));
}
Does anyone know why? Care to share the reason and whether this is a proper implementation? Mind that I'm not subscribing to this function anywhere else, but I keep piping the result.
here is where I call the method and return a response with a authorization header
public login(identifier): Observable<any> {
return generateToken(identifier).pipe(
catchError((err: Error) => of(err)),
map(token => {
return {'Authorization': token}
}));
}
and last but not least this function is converted in a promise and the response is returned as an http request
function async userLogin(identifier) {
return await login(identifier).toPromise();
}
Thanks for your time and patience
Upvotes: 2
Views: 252
Reputation: 11000
This explains your issue:
return await login(identifier).toPromise();
Promise resolves on Observable completion or rejects if it errors, so it works with take(1)
because it takes the first Observable value and completes it.
You can also get the output if you complete it. And it looks a bit more appropriate:
} else if (token) {
observer.next(token);
observer.complete(); <---
}
Upvotes: 1
Reputation: 841
take(1)
makes sure the subscriber.complete()
method is called right after the first item is emitted. BTW, this can be done directly by calling observer.complete()
after the observer.next()
.
toPromise()
will only resolve once the stream is completed, not on every emission.
Upvotes: 1
Reputation: 4868
Try
.pipe( () => take(1) );
Or
.pipe( take );
Same behavior happens in promises. The callback wants a function not a statement.
Upvotes: 0