ChanandlerBonggg
ChanandlerBonggg

Reputation: 25

React redux-observable: Making sequential API calls in an epic

I'm trying to make sequential API calls using redux-observable. The result data from the first API call should be used to make the next one. This post explains how to do it with rxjs in Angular, but I was not able to transfer the knowledge.

I've coded two epics, which I want to combine:

const createList: Epic = (action$) => action$.pipe(
  /*
  * Post a new empty list
  */
  ofType(CREATE_LIST),
  switchMap(({ payload }) => {
    const [postData, config] = prepareListRequest(payload);
    return from(axios.post<IAPIList>('http://127.0.0.1:8000/lists/', postData, config))
      .pipe(
        map(({ data }) => createListSuccessAction(data)),
        catchError((err) => of(ErrorAction(err))),
      );
  }),
);

const createItem: Epic = (action$) => action$.pipe(
  /*
  * Post a new item. Here the listID is in the payload. 
  */
  ofType(CREATE_ITEM),
  switchMap(({ payload }) => {
    const [postData, config] = prepareItemRequest(payload);
    return from(axios.post<IAPIItem>('http://127.0.0.1:8000/items/', postData, config,))
      .pipe(
        map(({ data }) => createItemSuccessAction(data)),
        catchError((err) => of(ErrorAction(err))),
    );
  }),
);

My goal: The first call posts an empty list, the second one takes the list.id response send back from the server and posts an item for that list. (striped down, just to make my goal clear)

const createPopulatedList: Epic = (action$) => action$.pipe(
  ofType(CREATE_POPULATED_LIST),
  res = firstAPICall(payload.list)
  secondAPICall(payload.item, res.id)
);

Thank you in advance for your time :)

Upvotes: 1

Views: 990

Answers (1)

backtick
backtick

Reputation: 2775

Take advantage of RxJS's ability to auto-convert promises to observables and use mergeMap + an async function.

const createPopulatedList = (action$) => action$.pipe(
  ofType(CREATE_POPULATED_LIST),
  mergeMap(async ({ list, item }) => {
    const { id } = await firstAPICall(list);
    return secondAPICall(item, id);
  })
);

Upvotes: 1

Related Questions