NgRx Effects error handling

  • what should effect do
  • what should effect do in case of error
  • what should user do in case of error
@Effect()
public fetchListOfTodos$: Observable<void> = this.action$.pipe(
ofType(ActionTypes.FETCH_TODO_LIST),
switchMap(() => this.todoListService.fetchTodoList()),
map((todos: Todo[]) => {
return {
type: ActionTypes.TODO_LIST_FETCHED,
payload: { todos }
};
}),
catchError((error) => {
return Observable.of({
type: ActionTypes.FETCH_TODO_LIST_FAILED,
payload: { error }
});
})
);
@Effect()
public fetchListOfTodos$: Observable<Action> = this.action$.pipe(
ofType(ActionTypes.FETCH_TODO_LIST),
switchMap(() =>
this.todoListService.fetchTodoList().pipe(
map((todos: Todo[]) => {
return {
type: ActionTypes.TODO_LIST_FETCHED,
payload: { todos }
};
}),
// handle failure in todoListService.fetchTodoList()
catchError((error) => {
return Observable.of({
type: ActionTypes.FETCH_TODO_LIST_FAILED,
payload: { error }
});
})
)
)
);

When catchError returns no action

@Effect()
public fetchListOfTodos$: Observable<Action> = this.action$.pipe(
ofType(ActionTypes.FETCH_TODO_LIST),
switchMap(() => this.todoListService.fetchTodoList()),
map((todos: Todo[]) => {
return {
type: ActionTypes.TODO_LIST_FETCHED,
payload: { todos }
};
}),
catchError((error, source$) => {
console.log(error);
return source$;
})
);

finalize() usage

@Effect()
public fetchListOfTodos$: Observable<Action> = this.action$.pipe(
ofType(ActionTypes.FETCH_TODO_LIST),
switchMap(() => {
store$.dispatch(ActionTypes.ShowLoadingSpinner());
return this.todoListService.fetchTodoList().pipe(
map((todos: Todo[]) => {
return {
type: ActionTypes.TODO_LIST_FETCHED,
payload: { todos }
};
}),
finalize(() => {
store$.dispatch(ActionTypes.HideLoadingSpinner());
})
);
}),
catchError((error, source$) => {
console.log(error);
store$.dispatch(ActionTypes.HideLoadingSpinner());
return source$;
}),
//finalize here gets never executed (even if no error ocurs), realized this after testing. If you need to do something after catchError, do it in catchError
//finalize(() -> {
// store$.dispatch(ActionTypes.HideLoadingSpinner());
//})
);

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Tomáš Trojčák

Tomáš Trojčák

3 Followers

Fullstack developer since 2007, Angular enthusiast since 2018