Chaining Network Requests

Learn the importance of chaining responses.

Sometimes to fetch data from the server, we have to make chained API calls. A simple example might be fetching the metadata of the current user and then the user’s actual profile from different endpoints. Here’s an example using an asynchronous action creator with redux-thunk:

const fetchCurrentUser = () => dispatch =>
 axios.get(`/user`)
  .then(({ data: user }) => {
    dispatch(setUser(user));

    // Get user's profile
    axios.get(`/profile/${user.profileId}`)
      .then(({ data: profile }) => dispatch(setProfile(profile)));
    }
  );

The solution appears to be quite straightforward, but there are a few issues with this code:

  • The exact branching and error catching are not obvious. They can become complex as the chain grows.
  • It is hard to debug and understand what stage we are in on the chain.
  • It is nearly impossible to cancel or abort the chain if the user navigates to a different part of the UI and the current request chain is no longer needed.

Chaining promises is not an ideal solution. Ultimately, we need to dispatch additional actions as a result of the previous action’s success. This specific case is called a side effect. We will study this in the following lessons.

There are many ways to achieve the same goal, but we are going to concentrate on just a few. Our API middleware should remain the same with any approach and only handle the network communication. The only thing that should be different is where and how we organize our flow logic.

Get hands-on with 1400+ tech skills courses.