Promise not resolved even when the request is done

I have a function that returns a promise from an HTTP Request:

getToken(id: string): Promise<string> {
    return this.service
      .getToken(id)
      .pipe(
        take(1)
        //catchError(() => of(null))
      )
      .toPromise();
}

And I want to know if the call failed (I won't have any token in this case), but the promise doesn't seem to complete because the IF statement is never reached if an error has occurred (BadRequest, Forbidden, etc.)

...
const token = await this.getToken(id);

if (!token) {
   console.log('no token');
}
...

But if I'm using catchError(() => of(null)), the promise completes even if the call failed and I can't understand the behavior.

2 answers

  • answered 2021-04-21 16:32 AliF50

    I am thinking the take(1) is for the success path only.

    Try this with no catchError:

    let token;
    try {
      token = await this.getToken(id);
    } catch (err) {
      console.log(err);
    }
    
    if (!token) {
     console.log('no token');
    }
    

    The try catch block should catch the error from the promise and proceed to the if(!token).

  • answered 2021-04-21 16:50 David B.

    I'm assuming that your service is using the angular HttpClient inside. As the Observables of the HttpClient will always return only one single result and complete after that, I don't get the reason you should need to use take(1). just do:

    getToken(id: string): Promise<string> {
      return this.service.getToken(id).toPromise();
    }
    

    The more angular (or rxjs) way would be to subscribe to the Observable or to transform that observable with pipe(map(data => doSomethingWithData(data)) and then subscribe to it, instead of converting it to a promise and wait for it to resolve. Checkout the rxjs operators to manipulate observables. Most important are: map,tap,switchMap,mergeMap,...