Search code examples
typescriptrxjsngrxngrx-storengrx-effects

ngrx effect - combining two API


I have the below effect to update a part of an object using the update api, then i get the whole object by findById api, so i used forkJoin to combine those two api, but i want the findById api to be executed after 1 second from the update api, so i used delay(1000), but it's not working

@Effect()
updateGeographicScope$ = this.actions$.pipe(
    ofType<conventionsActions.PatchGeographicScope>(conventionsActions.ConventionActionTypes.PATCH_GEOGRAPHIC_SCOPE),
    map(action => action.payload),
    exhaustMap(geographicScope => forkJoin(this.apiConvention.update(geographicScope),
        this.apiConvention.findById (geographicScope.externalId).pipe(delay(1000))).pipe(
            map(([first, convention]) => new conventionsActions.PatchSuccess({
                id: convention.externalId,
                changes: convention
            })),
            catchError(err => {
                console.error(err.message);
                return of(new conventionsActions.Failure({ concern: 'PATCH', error: err }));
            })
        ))
);

Solution

  • You need to use a concat and timer for that. With concat it the first stream to complete before starting the next one. So it makes update, then waits 1 second, then makes findById.

    @Effect()
    updateGeographicScope$ = this.actions$.pipe(
        ofType<conventionsActions.PatchGeographicScope>(conventionsActions.ConventionActionTypes.PATCH_GEOGRAPHIC_SCOPE),
        map(action => action.payload),
        mergeMap(geographicScope => concat(
          this.apiConvention.update(geographicScope).pipe(switchMapTo(EMPTY)), // makes a request
          timer(1000).pipe(switchMapTo(EMPTY)), // waits 1 sec
          this.apiConvention.findById(geographicScope.externalId), // makes a request
        )),
        map(convention => new conventionsActions.PatchSuccess({
          id: convention.externalId,
          changes: convention
        })),
        catchError(err => {
          console.error(err.message);
          return of(new conventionsActions.Failure({ concern: 'PATCH', error: err }));
        }),
        repeat(), // make active after a failure
      )),
    );