Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catch error in combined pipe of pipeable rxjs operators

We've just upgraded one of our applications to Angular 5, and started to transition into lettable operators as introduced in rxjs v5.5.

Because of this, we have rewritten our observable pipelines to the new syntax with the .pipe() operator.

Our previous code would look like this, with a .catch() inside the .switchMap() as to not interrupt the running of effects if an error is thrown.

@Effect() loadData$ = this.actions$ .ofType(LOAD_DATA) .map((action: LoadData) => action.payload) .withLatestFrom(this.store.select(getCultureCode)) .switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)   .map(result => {     if (!result) {       return new LoadDataFailed('Could not fetch data!');     } else {       return new LoadDataSuccessful(result);     }   })   .catch((err, caught) => {     return Observable.empty();   });   ); 

In the case of an error thrown in the call to the dataService it would be caught and handled (simplified the error handling here).

With the new syntax and use of .pipe(), we now have this

@Effect() loadData$ = this.actions$ .ofType(LOAD_DATA) .pipe(   map((action: LoadData) => action.payload),   withLatestFrom(this.store.select(getCultureCode)),   switchMap(([payload, cultureCode]) => this.dataService.loadData(payload, cultureCode)),   map(result => {     if (!result) {       return new LoadDataFailed('Could not fetch data!');     } else {       return new LoadDataSuccessful(result);     }   })   ); 

How can I in a similar fashion catch any thrown errors in the observable pipeline, using the new syntax?

like image 975
Daniel B Avatar asked Nov 15 '17 15:11

Daniel B


People also ask

How do you catch an error in observable?

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 throw an error in RxJS?

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

What is Pipeable operator in RxJS?

A Pipeable Operator is a function that takes an Observable as its input and returns another Observable. It is a pure operation: the previous Observable stays unmodified. A Pipeable Operator is essentially a pure function which takes one Observable as input and generates another Observable as output.


1 Answers

After refactoring you moved map out of switchMap projection, so any error will close the outer stream. To keep both streams equivalent, you need to use pipe in the projection itself like that:

import { EMPTY } from 'rxjs;  // ...  @Effect() loadData$ = this.actions$ .ofType(LOAD_DATA) .pipe(   map((action: LoadData) => action.payload),   withLatestFrom(this.store.select(getCultureCode)),   switchMap(([payload, cultureCode]) =>     this.dataService.loadData(payload, cultureCode)       .pipe(          map(result => {            if (!result) {              return new LoadDataFailed('Could not fetch data!');            } else {              return new LoadDataSuccessful(result);            }           }),          catchError((err, caught) => {            return EMPTY;          })       )   ) ); 
like image 179
artur grzesiak Avatar answered Oct 18 '22 20:10

artur grzesiak