Search code examples
rxjsngrx

How to get data from failed forkJoin request?


Using Angular Rxjs and ngrx

I have an action that dispatch 4 API and I am doing the following =>

  @Effect()
  getAllModels$ = this.actions$.pipe(
    ofType<featureActions.GetAllModelsRequest>(featureActions.ActionTypes.GetAllModelsRequest),
    switchMap((action) =>
      forkJoin([
        this.dataService.GetAllModelFromServer(),
        this.dataService.GetAllModelFromHost(),
        this.dataService.GetAllModelFromCache(),
        this.dataService.GetAllModelFromPreference(),
      ]).pipe(
        map(
          ([server, host, cache, preference]) =>
            new featureActions.GetAllModelsSuccess({
              //...
            })
        ),
        catchError((error: HttpErrorResponse) => {
          return of(new featureActions.GetAllModelsFailed({ error: error.message }));
        })
      )
    )
  );

The problem is, when one of those API fail, everything fail and I am in fail action. all the data that got retrieved (before the one endpoint that failed) is lost.

Is there a way to get the data retrieved in the catchError or the only solution is to chain the api one after the other ?


Solution

  • I went with this solution found here : https://medium.com/better-programming/rxjs-error-handling-with-forkjoin-3d4027df70fc

      @Effect()
      getAllModels$ = this.actions$.pipe(
        ofType<featureActions.GetAllModelsRequest>(featureActions.ActionTypes.GetAllModelsRequest),
        switchMap((action) =>
          forkJoin([
            this.dataService.GetAllModelFromServer().pipe(catchError(() => of({ data: [] }))),
            this.dataService.GetAllModelFromHost().pipe(catchError(() => of({ data: [] }))),
            this.dataService.GetAllModelFromCache().pipe(catchError(() => of({ data: [] }))),
            this.dataService.GetAllModelFromPreference().pipe(catchError(() => of({ data: [] }))),
          ]).pipe(
            map(
              ([server, host, cache, preference]) =>
                new featureActions.GetAllModelsSuccess({
                  //...
                })
            ),
            catchError((error: HttpErrorResponse) => {
              return of(new featureActions.GetAllModelsFailed({ error: error.message }));
            })
          )
        )
      );