Back to homepage

πŸ“ͺ All or Nothing data fetching with in ReactJS

try {
const [userRes, orgRes, projectRes] = await Promise.all([
axios.get(`${BACKEND_URL}/api/users/`, {
headers: { Authorization: `Token ${token}` },
}),
axios.get(`${BACKEND_URL}/api/organizations/`, {
headers: { Authorization: `Token ${token}` },
}),
axios.get(`${BACKEND_URL}/api/projects/`, {
headers: { Authorization: `Token ${token}` },
}),
]);
setUsers(userRes.data);
setOrgs(orgRes.data);
setProjects(projectRes.data);
} catch (error) {
console.error("Data fetch failed:", error);
setUsers([]); // Reset to safe empty state
setOrgs([]);
setProjects([]);
}

making 3 API requests in parallel to fetch:

  • Users ()
  • Organizations ()
  • Projects ()

using , which means:

  • All requests are sent at the same time (not one after another).
  • It waits for all of them to finish.
  • Once done, the responses are stored in:
    • β†’ users data
    • β†’ organizations data
    • β†’ projects data

You're running 3 API requests in parallel with . That means:

  • If any one of the 3 requests fails, the entire fails, and none of the results (, , ) are available.
  • If you don’t handle that error with a , your app might crash or enter an unexpected state.
  • If you do handle it with , and inside the you do:

🧠 Why set empty arrays in error?

  • βœ… To prevent the app from trying to render stale/partial data.
  • βœ… To show "No data" or fallback UI.
  • βœ… To avoid crashing due to .

using is a good thing here β€” if:

  1. All 3 API requests are independent (users, orgs, projects don’t depend on each other).
  2. You want to fetch them in parallel to save time (it's faster than doing one after another).

πŸ“ˆ Benefits of in this case:

  • Speed: All three requests start at once, so ==total time = time of the slowest one.==
  • Clean code: Easier to manage than chaining separate calls.
  • Single failure point: If you want ==all-or-nothing data fetching.==

⚠️ But has a downside:

If any one request fails, will reject, and you’ll get no data at all, even if others succeed.

When to use instead?

If you want to continue with whatever data is available (even if one fails):

const [userRes, orgRes, projectRes] = await Promise.allSettled([
axios.get(`${BACKEND_URL}/api/users/`, { headers: { Authorization: `Token ${token}` } }),
axios.get(`${BACKEND_URL}/api/organizations/`, { headers: { Authorization: `Token ${token}` } }),
axios.get(`${BACKEND_URL}/api/projects/`, { headers: { Authorization: `Token ${token}` } }),
]);
if (userRes.status === 'fulfilled') setUsers(userRes.value.data);
else setUsers([]);
if (orgRes.status === 'fulfilled') setOrgs(orgRes.value.data);
else setOrgs([]);
if (projectRes.status === 'fulfilled') setProjects(projectRes.value.data);
else setProjects([]);

πŸ”Ž Summary

Use CaseUse ?Use ?
Want all-or-nothing resultsβœ… Yes❌ No
Want partial data if one fails❌ Noβœ… Yes
Requests are independentβœ… Yesβœ… Yes