NGRX Effects - Waiting for other actions
You have A and B as features in NGRX.
A actions:
- loadA
- loadASuccess
- loadAFailure
B actions:
- loadB
- loadBSuccess
- loadBFailure
You want feature C (with loadC / loadCSuccess / loadCFailure) to:
- Emit its success after making sure that A and B did not fail.
- Aggregate loadASuccess and loadBSuccess with another observable.
Here’s the switchMap for C’s Effect:
switchMap(action => {
// load A
this.store.dispatch(loadA);
const a$ = this.actions$.pipe(
ofType(loadASuccess), // filter on loadASuccess
takeUntil(this.actions$.pipe(ofType(loadAFailure))), // complete without emitting on loadAFailure
first(), // emit error if completed without an emit, otherwise complete after first emit.
);
// load B
this.store.dispatch(loadB);
const b$ = this.actions$.pipe(
ofType(loadBSuccess), // filter on loadBSuccess
takeUntil(this.actions$.pipe(ofType(loadBFailure))),// complete without emitting on loadBFailure
first(), // emit error if completed without an emit, otherwise complete after first emit.
);
// wait for both a$ and b$ to complete. if any fails, error is thrown to pipe.
return forkJoin({
a: a$,
b: b$,
}).pipe(
first(), // take(1) is also ok here.
map(() => loadCSuccess()), // processing, then returning the event here.
catchError(error => loadCFailure({ error: error?.error })) // on any error, emit loadCFailure.
);
})
Remember to catchError inside inner scope of switchMap (as done above), otherwise Effect will not trigger again.