Blog>
Snippets

Handling Nested API Responses

Show a createAsyncThunk example where the response from an API request contains nested resources that require subsequent recursive API calls.
import { createAsyncThunk } from '@reduxjs/toolkit';

// Define the asynchronous thunk using createAsyncThunk
export const fetchNestedData = createAsyncThunk(
  'data/fetchNested',
  async (initialArg, thunkAPI) => {
    try {
      // Make the initial API call
      const response = await fetch(`https://example.com/api/resource/${initialArg}`);
      const data = await response.json();

      // Check for nested resources in the response
      if(data.nestedResources && Array.isArray(data.nestedResources)) {
        // Recursively fetch nested resources
        const nestedResponses = await Promise.all(
          data.nestedResources.map(async (nestedResource) => {
            const nestedResponse = await fetch(`https://example.com/api/nested/${nestedResource.id}`);
            return await nestedResponse.json();
          })
        );
        // Combine the initial data with the nested responses
        return { ...data, nestedResponses };
      }

      return data;
    } catch (error) {
      // Auto-generates a 'rejected' action dispatch
      return thunkAPI.rejectWithValue(error.message);
    }
  }
);
This code defines an asynchronous thunk named fetchNestedData that uses createAsyncThunk to handle an API request which contains nested resources. Initially, it makes a request to fetch the main resource. On successful retrieval, it checks if there are nested resources to be fetched as well. If so, it performs a recursive API call for each nested resource using Promise.all to fetch them concurrently. Once all nested resources are retrieved, their data is combined with the initial data, and the aggregate is returned. If any error occurs, it uses rejectWithValue to return the error.