I would like to make two treatments on a same api call data.
I have a first effect:
loadSchedulings$ = createEffect(() =>
this.actions$.pipe(
ofType(ESchedulesActions.GetSchedulesByDate),
mergeMap(() =>
this.apiCallsService.getSchedulings().pipe(
map(trips => ({ type: ESchedulesActions.GetSchedulesByDateSuccess, payload: trips })),
catchError(() => EMPTY)
)
)
)
);
I call getSchedulings
service method which make an api call then a treatment 1 on data is done
ApiCallsService :
getSchedulings() {
return this.http.get<ISchedules>(this.SchedulingByDateLocal2).pipe(
...
return groupByDate;
})
);
}
I would like to make a second treatment on the same data source. (raw data got from api ) but in parallel of the first because they are independent
So by logic I create a second effect
loadDirections$ = createEffect(() =>
this.actions$.pipe(
ofType(ESchedulesActions.GetSchedulesByDate),
mergeMap(() =>
this.apiCallsService.getDirections().pipe(
map(trips => ({ type: ESchedulesActions.GetDirectionsByDateSuccess, payload: directions})),
catchError(() => EMPTY)
)
)
)
);
Then in apiCallService I should have a method
getDirections() {
return this.http.get<ISchedules>(this.SchedulingByDateLocal2).pipe(
...
return groupByDirections;
})
);
}
The problem here is that I will have two requests for the same data.
To summarize the actual workflow :
LoadSchedulings ( effect ) ==> loadSchedulings ( service ) ==> API Call ==> treatment 1 LoadDirections ( effect ) ==> loadDirections ( service ) ==>(Same) API Call ==> treatment 2
So I would like to only use the first api request's data for two treatments
Update: According to the response of Manuel Panizzo I should have something like this ?
getRawData() {
return this.http.get<ISchedules>(this.SchedulingByDateLocal2)
}
Effect.ts
loadSchedulings$ = createEffect(() =>
this.actions$.pipe(
ofType(ESchedulesActions.getRawData),
pipe((data) =>
this.apiCallsService.getSchedulings(data).pipe(
map(trips => ({ type: ESchedulesActions.GetSchedulesByDateSuccess, payload: trips })),
catchError(() => EMPTY)
)
),
pipe((data) =>
this.apiCallsService.getDirections(data).pipe(
map(directions=> ({ type: ESchedulesActions.GetDirectionsByDateSuccess, payload: directions})),
catchError(() => EMPTY)
)
),
)
);
I think you could also dispatch a getRawDataSuccess
action (that performs 1 api call)
getRawData$ = createEffect(() =>
this.actions$.pipe(
ofType(ESchedulesActions.getRawData),
mergeMap(() =>
this.apiCallsService.getRawData().pipe(
map(data => ({ type: ESchedulesActions.GetRawDataSuccess, payload: data })),
catchError(err => ({ type: ESchedulesActions.GetRawDataError, payload: err }))
)
)
)
);
Then create one effect per treatment listening for getRawDataSuccess
action:
getSchedulesByDate$ = createEffect(() =>
this.actions$.pipe(
ofType(ESchedulesActions.getRawDataSuccess),
map((action) => {
return {
type: ESchedulesActions.GetSchedulesByDateSuccess,
payload: action.payload.schedulesByDate,
}
})
)
);
getDirectionsByDate$ = createEffect(() =>
this.actions$.pipe(
ofType(ESchedulesActions.getRawDataSuccess),
map((action) => {
return {
type: ESchedulesActions.GetDirectionsByDateSuccess,
payload: action.payload.directionsByDate,
}
})
)
);
This would be cleaner IMO and will theoretically run in parallel too.