Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between onError in subscribe and catch operator?

I've came across two types of error handling in RxJS:

  • using the second argument (onError) in the subscribe
  • using the catch operator.

What is the difference between them? What are some textbook examples or rule-of-a-thumbs for using either of them?


this.stream$.subscribe(callback, err => console.error(err))

// vs

this.stream$.catch(err => console.error(err)).subscribe(callback)
like image 440
Lazar Ljubenović Avatar asked Oct 15 '25 18:10

Lazar Ljubenović


2 Answers

In your example you would get the same output in both cases. As for rules of thumb:

  • Use do if you want to do something with the error (e.g. log it) and you do not want to create a subscription. You might do this if you were, for example, wrapping some library (e.g. angular's Http library) in a generic wrapper that adds logging (maybe pops up a toast at the bottom of the screen when an error occurs).
  • Use subscribe if you want to do something with the error (e.g. log it) and you want to create a subscription. Keeping with that Http example this might be if you want to kick off a request and display any error that surfaces in the same place you were going to put the response.
  • Use catch if you want to handle the error and recover. For example, maybe you want to catch a 401 error, refresh login credentials, and then retry the request.

In your example, since you are just logging the error, catch would be inappropriate.

like image 151
Pace Avatar answered Oct 17 '25 08:10

Pace


The callback on a subscribe is the end of the chain, you just listen to the result.

catch is an operator that lets you change the behavior of your observable when an error is thrown or just replace the error with another value. catch expect you to do something, to return a new observable not just listen to it.

Also, you can use do inside a chain to listen to an observable like you do on subscribe.

*For RxJs 6 *

Use tap instead of do. Use catchError instead of catch. Use finalize instead of finally

And for all of the parameters above, you need to use a pipe:

this.service.getItem()
    .pipe(
        map((data) => this.onSuccess(data)),
        catchError(error => of(this.handleError(error))),
        finalize(() => this.stopLoading())
    )
    .subscribe();

Also, imports have changed. Now you should import like that:

Import { tap, catchError } from 'rxjs/operators';

Plus, you don't need to import pipe.

like image 30
Arthur Costa Avatar answered Oct 17 '25 09:10

Arthur Costa