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?
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