Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to throw error from RxJS map operator (angular)

I want to throw an error from my observable's map operator based on a condition. For instance if correct API data is not received. Please see the following code:

private userAuthenticate( email: string, password: string ) {     return this.httpPost(`${this.baseApiUrl}/auth?format=json&provider=login`, {userName: email, password: password})         .map( res => {              if ( res.bearerToken ) {                 return this.saveJwt(res.bearerToken);              } else {                 // THIS DOESN'T THROW ERROR --------------------                 return Observable.throw('Valid token not returned');             }         })         .catch( err => Observable.throw(this.logError(err) )         .finally( () => console.log("Authentication done.") ); } 

Basically as you can see in the code, if the response (res object) doesn't have bearerToken I want to throw out an error. So that in my subscription it goes into the 2nd parameter (handleError) mentioned below.

.subscribe(success, handleError) 

Any suggestions?

like image 354
Hassan Avatar asked Apr 04 '17 06:04

Hassan


People also ask

How do I get an observable error message?

Catch errors in the observable stream Another option to catch errors is to use the CatchError Operator. The CatchError Operators catches the error in the observable stream as and when the error happens. This allows us to retry the failed observable or use a replacement observable.

How do you handle errors in Mergemap?

You'll need to use retry or retryWhen (names are pretty self-explanatory) — these operators will retry a failed subscription (resubscribe to the source observable, once an error is emitted.


1 Answers

Just throw the error inside the map() operator. All callbacks in RxJS are wrapped with try-catch blocks so it'll be caught and then sent as an error notification.

This means you don't return anything and just throw the error:

map(res => {    if (res.bearerToken) {     return this.saveJwt(res.bearerToken);    } else {     throw new Error('Valid token not returned');   } }) 

The throwError() (former Observable.throw() in RxJS 5) is an Observable that just sends an error notification but map() doesn't care what you return. Even if you return an Observable from map() it'll be passed as next notification.

Last thing, you probably don't need to use .catchError() (former catch() in RxJS 5). If you need to perform any side effects when an error happens it's better to use tap(null, err => console.log(err)) (former do() in RxJS 5) for example.

Jan 2019: Updated for RxJS 6

like image 152
martin Avatar answered Oct 05 '22 12:10

martin