0

I need to fetch values from another API using the guid inside this particular array, then group them together (hence I used reduce Javascript in this case) However, I could not get those values sumEstimatedHours and sumWorkedHours as expected. Can someone suggest a method please?

export const groupProjectsByPM = (listOfProjects) => {
  const dir = "./json";
  const estimatedHours = fs.existsSync(dir)
    ? JSON.parse(fs.readFileSync("./json/phases.json", "utf-8"))
    : null;
  let sumWorkedHours, sumEstimatedHours;

  const groupedProjects = listOfProjects?.reduce(
    (
      group,
      {
        guid,
        projectOwner: { name: POName },
        name,
        customer: { name: customerName },
        deadline,
        calculatedCompletionPercentage,
      }
    ) => {
      listOfProjects.map(async (element, index) => {
        // const element = listOfProjects[index];
        sumWorkedHours = await getWorkhoursByProject(element?.guid).then(
          (res) => {
            return res.reduce((acc, cur) => {
              return acc + cur.quantity;
            }, 0);
          }
        );

        const filteredEstimatedHours = estimatedHours.filter(
          (item) => item.project.guid === element.guid
        );

        sumEstimatedHours = filteredEstimatedHours.reduce((acc, cur) => {
          return acc + cur.workHoursEstimate;
        }, 0);
        group[POName] = group[POName] || [];
        group[POName].push({
          guid,
          name,
          POName,
          customerName,
          deadline,
          calculatedCompletionPercentage,
          sumEstimatedHours,
          sumWorkedHours,
        });
        return group;
      });

      return group;
    },
    []
  );

  return groupedProjects;
};
Henry.
  • 21
  • 6
  • 1
    https://zellwk.com/blog/async-await-in-loops/ helped me to understand nuances of async functions in loops – capchuck Aug 02 '22 at 18:31
  • Just don't use `reduce` for grouping. Use a regular loop and the `async`/`await` will work as expected. – Bergi Aug 29 '22 at 12:50

1 Answers1

-1

here is an example of async/await inside reduce:

let's assume that we have an array of numbers

const arrayOfNumbers = [2,4,5,7,6,1];

We are going to sum them using reduce function:

const sumReducer = async () => {

  const sum = await arrayOfNumbers.reduce(async (promisedSum, num) => {
    const sumAcc = await promisedSum
    // any promised function can be called here..
    return sumAcc + num
  }, 0)

  console.log(sum)
}

So the trick is to remember to await the accumulator inside the reduce function

export const groupProjectsByPM = async (listOfProjects) => {
  const dir = "./json";
  const estimatedHours = fs.existsSync(dir)
    ? JSON.parse(fs.readFileSync("./json/phases.json", "utf-8"))
    : null;
  let sumWorkedHours, sumEstimatedHours;

  const groupedProjects = await listOfProjects?.reduce(
    async (
      promisedGroup,
      {
        guid,
        projectOwner: { name: POName },
        name,
        customer: { name: customerName },
        deadline,
        calculatedCompletionPercentage,
      }
    ) => {
      listOfProjects.map(async (element, index) => {
        //accumulator in your case is group
        const group = await promisedGroup;

        // const element = listOfProjects[index];
        sumWorkedHours = await getWorkhoursByProject(element?.guid).then(
          (res) => {
            return res.reduce((acc, cur) => {
              return acc + cur.quantity;
            }, 0);
          }
        );

        const filteredEstimatedHours = estimatedHours.filter(
          (item) => item.project.guid === element.guid
        );

        sumEstimatedHours = filteredEstimatedHours.reduce((acc, cur) => {
          return acc + cur.workHoursEstimate;
        }, 0);
        group[POName] = group[POName] || [];
        group[POName].push({
          guid,
          name,
          POName,
          customerName,
          deadline,
          calculatedCompletionPercentage,
          sumEstimatedHours,
          sumWorkedHours,
        });
        return group;
      });

      return group;
    },
    []
  );

  return groupedProjects;
};

Best of luck ...

M.N
  • 11
  • 5