cdSo I'm trying to migrate some of my Angular 5 code to 6, and I understand most of the changes required for rxjs to work using the .pipe() operator. It works as you would expect for 'pipable' operations.
However, the behavior of catchError()
is different than the .catch()
operator. Prior to rxjs 6 I used the .catch()
operator to transform the error input into a a consistent error object that can then be caught in the `.subscribe().
getAlbums(): Observable<Album[]> {
return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
.map(albumList => this.albumList = albumList)
.catch(new ErrorInfo().parseObservableResponseError);
}
new ErrorInfo().parseObservableResponseError
is a function that takes a error object as input and parses the input error into a simpler error object with a normalized object. Catch returns Observable<any>
:
parseObservableResponseError(response): Observable<any> {
let err = new ErrorInfo();
...
return Observable.throw(err);
}
This worked great for easily handling errors up rxjs5 - errors basically are captured as part of the pipeline and then throw a well known error structure that can be captured .subscribe()
error function.
Moving that same code to rxjs 6 however and using .pipe()
I am trying to do the following:
getAlbums(): Observable<Album[]> {
return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
.pipe(
map(albumList => this.albumList = albumList),
catchError(new ErrorInfo().parseObservableResponseError)
);
}
However this doesn't work because catchError now returns a result of Observable<any>
into the pipeline, which is not what I want here. In essence I just want to re-throw any errors as I did before.
error TS2322: Type 'Observable<{} | Album[]>' is not assignable to type 'Observable'
How do simulate the old operator .catch()
behavior?
Update:
After mucking around with this a bit more, the code as shown just started working without giving me a build error. Honestly I have no idea why it failed with the error message before, but is working now. The suggestion by @cartant in the comments is an explicit way to specify the result and that works as well.
catchError method Null safety Handles errors emitted by this Future. This is the asynchronous equivalent of a "catch" block. Returns a new Future that will be completed with either the result of this future or the result of calling the onError callback.
The right way to handle the RxJS error is by putting the “catchError” inside the http. get “pipe”. It will end the http. get observable but that doesn't matter because it is a finite observable anyways and only emits one value.
RxJS catchError() operator is an error-handling operator used to handle and take care of catching errors on the source observable by returning a new observable or an error.
The catchError operator takes as input an Observable that might error out, and starts emitting the values of the input Observable in its output Observable. If no error occurs, the output Observable produced by catchError works exactly the same way as the input Observable.
You should be able to explicitly specify the type parameters to catchError
to indicate that it won't return an observable that emits a value - that is, it will return Observable<never>
- and will always throw:
getAlbums(): Observable<Album[]> {
return this.httpClient.get<Album[]>(this.config.urls.url("albums"))
.pipe(
map(albumList => this.albumList = albumList),
catchError<Album[], never>(new ErrorInfo().parseObservableResponseError)
);
}
Doing so will see the type inferred from the pipe
call to be Observable<Album[]>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With