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.