I need to dispatch multiple actions from an ngrx effect once an http request is successful.
There are several ways that seem to work and some that don't, I can't understand what the difference is.
@Effect()
loadUser = this.actions
.pipe(
ofType(campaignActions.type.LOAD_CAMPAIGN),
map((action: userActions.LoadUserAction) => action.payload),
switchMap((payload: { id: number }) =>
this.s.getUser(payload.id)
.pipe(
switchMap((data) => {
return from([
new userActions.LoadUserSuccessAction(),
new userActions.SomethingElseSuccessAction()
]);
}),
catchError(() => of(new userActions.LoadUserFailureAction()))
)
)
);
First of all, I can use switchMap or mergeMap. I believe the difference is that if this effect is triggered multiple times, any ongoing requests will be cancelled if I use switchMap and not if I use mergeMap.
In terms of dispatching multiple actions, all the following works:
The following doesn't work:
What is the difference between all the first 3 options? What about mergeMap vs switchMap after the http request? Why doesn't the last option work?
This question can be separated into few sections:
+) Difference between mergeMap and switchMap:
mergeMap = map + mergeAll. It maps a data stream to observable stream, and everytime the inner observable emits a value, the outer will collect and merge all emitted value into a new stream.
switchMap, very similar, but as you can tell it "switches", i.e. if the next inner observable emits a new value, the previous one gets canceled (one inner observable at a time).
+) Similarity between mergeMap and switchMap: They can both convert any stream-like object to an observable.
+) Difference between your code:
return [action1, action2] does indeed make switchMap(() => ...) similar to from([action1, action2]), i.e. create an observable from an array.
return from([action1, action2]), this is an inner observable that emits 2 actions, and switchMap merges those actions back to its stream.
return of(action1, action2) = from([action1, action2])
return of([action1, action2]), however, creates an observable that emits a single value, which is an array, and you cannot call store.dispatch(array_of_actions)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With