user3353167
user3353167

Reputation: 892

Why does take trigger the Observable?

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

Answers (3)

Julius Dzidzevičius
Julius Dzidzevičius

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

Nitsan Avni
Nitsan Avni

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

Wayne Smith
Wayne Smith

Reputation: 4868

Try

.pipe( () => take(1) );

Or

.pipe( take );

Same behavior happens in promises. The callback wants a function not a statement.

Upvotes: 0

Related Questions