0

I need to fetch all direct reports for the logged in manager and then display a card component for each one. I have to make a separate async call getPhoto(id) for each report by iterating over the response array of employee objects.

The following is my original attempt, which after running eslint, I realized is inefficient due to the sequential await's inside the for...of loop.

async function getReports() {
  const response = await fetch('/current_user_direct_reports')
    .then(res => res.json())
    .then(data => data.value)
    .catch(error => console.log(error));

  for (const report of response) {
    report.photo = await getPhoto(report.userPrincipalName);
  }

  setReports(response)
}

useEffect(() => {
  getReports();
}, []);

This works but is rather slow. I tried adjusting the code to collect a list of employee objects, each containing a photo Promise, in order to allow all requests to resolve simultaneously.

async function getReports() {
  const response = await fetch('/current_user_direct_reports')
    .then(res => res.json())
    .then(data => data.value)
    .catch(error => console.log(error));

  const reportsAndPhotos = [];
  for (const report of response) {
    const emp = report;
    emp.photo = getPhoto(report.userPrincipalName);
    reportsAndPhotos.push(emp);
  }

  return (await Promise.all(reportsAndPhotos));
}

useEffect(() => { 
  async function getEmployees() {
    const reportsAndPhotos = await getReports();
    setReports(reportsAndPhotos);
    setLoaded(true);
  }
  getEmployees();
}, []);

However, my response is repeatedly rendered empty and I cannot identify what I'm doing wrong. I thought Promise.all() would wait for everything to resolve before returning.

  • 1
    `emp.photo` is the promise, so `Promise.all([emp, emp, …])` where `emp` isn’t a promise doesn’t make sense. – Ry- Aug 14 '19 at 19:55
  • 1
    `Promise.all()` expects an array of promises, not an array of objects with properties that are promises. To say what @Ry- said a little differently :). – Heretic Monkey Aug 14 '19 at 19:56
  • Ah, thank you both! Now my question is - if I were to adjust to pull back only photos and use `Promise.all()` on that array, how can I maintain the connection between an employee and their specific photo? Since of course I wouldn't be able to trust the order in which they were fetched – jasonkylemorse Aug 14 '19 at 20:04
  • @jasonkylemorse Doesn't matter when the fetch responses arrive, you [can trust the order of the `Promise.all` results](https://stackoverflow.com/a/28066825/1048572). – Bergi Aug 14 '19 at 20:08
  • @Bergi Perfect, thank you very much for the info! – jasonkylemorse Aug 14 '19 at 20:20

0 Answers0