Home > database >  Merge multiple responses and dispatch success once only
Merge multiple responses and dispatch success once only

Time:09-20

I have the following code which loops through ids and returns response for each ID separately one by one.

refresh$ = createEffect(() =>
      this.actions$.pipe(
        ofType(CustomerActions.refresh),
        delay(1000),
        WithLatestFrom(this.facade.customerIds$),
        exhaustMap(([_, customerIds]) =>
          merge(
            ...customerIds.map((id) =>
              this.customersService.getCustomer(id).pipe(
                map(CustomerActions.getCustomerSuccess),
                catchError((err) =>
                  of(CustomerActions.getCustomerFailed(id, err.message)),
                ),
              ),
            ),
          ),
        ),
      ),
    )

I want to combine the response and get all responses together for customerIds.

I tried moving merge first and then mapping the results, but it resulted in multiple success to be called. Any suggestions?

CodePudding user response:

You can use the forkJoin operator, it behaves like Promise.all it will wait until all the inner observables complete and then emit the values.

After the forkJoin emits the values you can dispatch the success action.

refresh$ = createEffect(() =>
      this.actions$.pipe(
        ofType(CustomerActions.refresh),
        delay(1000),
        WithLatestFrom(this.facade.customerIds$),
        exhaustMap(([_, customerIds]) =>
          forkJoin(
            ...customerIds.map((id) =>
              this.customersService.getCustomer(id).pipe(
                catchError((err) =>
                  of(CustomerActions.getCustomerFailed(id, err.message)),
                ),
              ),
            ).pipe(
              map(CustomerActions.getCustomerSuccess),
            ),
          ),
        ),
      ),
    )
  • Related