infodev
infodev

Reputation: 5245

Ngrx effect parallel http call

I have an effect that should call two different APIs (API1 and API2).

Here's the effect

$LoadKpiMission = createEffect(() =>
  this.actions$.pipe(
    ofType<any>(EKpiActions.GetMissionsByStation),
    mergeMap(action =>
      this.apiCallsService.getKpi(action.payload, '2016-04-18').pipe(
        map(trips => ({ type: EKpiActions.GetMissionsSuccess, payload: trips })),
        catchError(() => EMPTY)
      )
    )
  )
);

Here's the structure of the service

getKpi(station: number, date: string) {
  let Kpi = `http://192.168.208.25:8998/api/scheduling/circulation_by_date_and_station?orig=${station}&date=${date}`;
  return this.http.get<ISchedules>(API1).pipe(
    map(data => {
      return this.formatDataToKpi1(data);
    })
  );
}

However, I have to retrieve additional data from API2 and merge it with the data returned from API1.

I should do that inside the formatDataToKpi1 function.

I would like to know how to run requests in parallel and pass the returned responses to formatDataToKpi1 and do treatment then return to the effect ?

Upvotes: 2

Views: 1043

Answers (1)

wentjun
wentjun

Reputation: 42536

You can make use of the forkJoin RxJS operator.

As stated on the documentation,

When all observables complete, emit the last emitted value from each.

This way, when the observables from both requests have been completed, it will be returned, and you can carry out the subsequent operations.

$LoadKpiMission = createEffect(() =>
  this.actions$.pipe(
    ofType<any>(EKpiActions.GetMissionsByStation),
    mergeMap(action =>
      const getKpi = this.apiCallsService.getKpi(action.payload, '2016-04-18');
      const getKpi2 = this.apiCallsService.getKpi2();

      forkJoin(getKpi, getKpi2).subscribe(([res1, res2] => {
        // do the rest here
      });

    )
  )
);

EDIT: Looks like I have initially misunderstood your question - Was a bit confused by the variable names

getKpi(station: number, date: string) {
  let Kpi = `http://192.168.208.25:8998/api/scheduling/circulation_by_date_and_station?orig=${station}&date=${date}`;

  const api1 = this.http.get<ISchedules>(API1);
  const api2 = this.http.get<ISchedules>(API2);

  return forkJoin(api1, api2).pipe(
    map(data => {
      return this.formatDataToKpi1(data);
    })
  );
}

Upvotes: 4

Related Questions