Reputation: 175
I have a redux-observable epic which polls an API and I'm trying to execute three dependent, sequential http requests and gather all responses in an array.
toArray() is never executed in this case because concatMap() is not finished. I tried to move the calls inside of a mergeMap() and gather the array there, but only the last call was in the array.
timer(0, POLLING_INTERVAL).pipe(
concatMap(() => from(fetchApi(url1))),
concatMap(response => {
const url2 = 'URL based on first response';
return from(fetchApi(url2));
}),
concatMap(response => {
const url3 = 'URL based on second response';
return from(fetchApi(url3));
}),
toArray(), // expected [{response1}, {response2}, {response3}]
map(data => ({
type: ActionTypes.FETCH_SUCCESS,
payload: { data },
})),
catchError(error =>
of({
type: ActionTypes.FETCH_FAILED,
payload: { error },
}),
),
takeUntil(
action$.pipe(
ofType(ActionTypes.CANCEL_POLLING),
),
),
);
Upvotes: 1
Views: 546
Reputation: 96891
This depends on what you want to do. toArray()
won't help you because timer
never completes and toArray()
emits only when its source completes.
Maybe you're looking for something like this:
timer(0, POLLING_INTERVAL).pipe(
concatMap(() => from(fetchApi(url1)).pipe(
concatMap(response1 => {
const url2 = 'URL based on first response';
return forkJoin([of(response1), fetchApi(url2)]);
}),
concatMap(([response1, response2]) => {
const url3 = 'URL based on second response';
return forkJoin([of(response1), of(response2), fetchApi(url3)]);
}),
)),
map(data => ({
type: ActionTypes.FETCH_SUCCESS,
payload: { data },
})),
...
Upvotes: 1