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;
};
2
  • 1
    zellwk.com/blog/async-await-in-loops helped me to understand nuances of async functions in loops Commented Aug 2, 2022 at 18:31
  • Just don't use reduce for grouping. Use a regular loop and the async/await will work as expected. Commented Aug 29, 2022 at 12:50

1 Answer 1

-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 ...

Sign up to request clarification or add additional context in comments.

1 Comment

I made a small correction and applied the solution on your code ..

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.