I have an effect in NgRX effect, as follows:
$createOrganisation = createEffect(() =>
this.actions$.pipe(
ofType(fromOrganisationActions.createOrganisation),
switchMap((data) => this.organisation.createOrganisation(data)),
map((response) => fromOrganisationActions.createOrganisationSuccess({ orgId: response.id })),
catchError((error) => {
return of(fromOrganisationActions.createOrganisationError(error));
})
)
);
However, my stream never seems to end when the catchError
is triggered, i.e. in the instance of this.organisation.createOrganisation
returning a 400 error.
The action, fromOrganisationActions.createOrganisationError(error)
is triggered and my reducer is triggered from this... but if I re-trigger the fromOrganisationActions.createOrganisation
effect, this effect runs but the API call is never made a second time.
If I configure it as follows, and dispatch it manually, it works:
$createOrganisation = createEffect(() =>
this.actions$.pipe(
ofType(fromOrganisationActions.createOrganisation),
switchMap((data) => this.organisation.createOrganisation(data)),
map((response) => fromOrganisationActions.createOrganisationSuccess({ orgId: response.id })),
catchError((error) => {
this.store.dispatch(fromOrganisationActions.createOrganisationError(error));
return throwError(error);
})
)
);
But other examples online suggest the first way should work, but it is not for me, and I do not understand why my stream never ends.
Can somebody please advise and tell me why my stream never ends in the first instance?
The catchError should be added to the inner observable.
$createOrganisation = createEffect(() =>
this.actions$.pipe(
ofType(fromOrganisationActions.createOrganisation),
switchMap((data) => this.organisation.createOrganisation(data).pipe (
map((response) =>
fromOrganisationActions.createOrganisationSuccess({ orgId: response.id })),
catchError((error) => {
return of(fromOrganisationActions.createOrganisationError(error));
})
)),
)
);
These mistakes can be caught with eslint-plugin-ngrx, more details about the rule here.