I have an Angular app with NgRx, inside one of my effects I have a non expected behavior that, turns out, is expected, but I don't know how to fix it.
My minified code is
@Effect()
detelete$ = this.actions$
.pipe(
ofType<fromActions.DeleteRequested>(fromActions.ActionTypes.DeleteRequested),
map(action => action.payload.id),
mergeMap(id =>
combineLatest([
of(id),
this.rservice.deleteById(id)
.pipe(
catchError((err, caught$) => {
this.store.dispatch(new fromActions.DeleteCancelled({id: id}));
return caught$;
})
)
])
),
map(([id, ]: [string, any]) => {
return new fromActions.DeleteSuccess({id: id});
}),
);
The reason I don't have my catchError on the same level as my mergeMap is that I need my id as payload for my fromActions.DeleteCancelled action. Plus, my service only returns a boolean, so I use combineLatest to persist it to my onSuccess map.
What I'm experiencing is this catchError is executing multiple times. Thus, dispatching my error action multiple times.
I foun that
If you return this source, the observable will effectively restart all over again and retry
In this case the source is my caught$.
If, inside my cacthError I return
return of(new fromActions.DeleteCancelled({id: id}));
It will still go to my onSuccess map. I could maybe check if my second param inside that map is os type Action or boolean, but I think there's a proper way to handle it and I don't know it.
StackBlitz (uncomment subscribe to see infinite loop)
Thanks.
return [new fromActions.DeleteCancelled({id: id})];? - user2216584