Map and Async problems, values seem to be differing, how do i work with this async problem

Viewed 30

Just trying to sum up the values from a database and then take average for a parameter, and things wont work as expected, since project 1 and 2 are 100 and 33, it is supposed to be 66.5 for both the users, but only one of them gets the required output, please help me out, newbieeeee :(

Seems to work sometimes and sometimes it doesnt, but you know the drill, work it all or not ;-;

const sumItUp = async (project, sum) => {
  // console.log(project);
  await Project.findById(project, (err, result) => {
    // console.log(result.completion_percentage);
    sum += result.completion_percentage;
    console.log(result.title + " " + sum);
  });
  return sum;
};
const updateUserCompletion = async (user) => {
  // console.log(user);
  let sum = 0;
  for (var i = 0; i < user.projects.length; i++) {
    sum = await sumItUp(user.projects[i], sum);
    // console.log(user.name + " " + user.project[i].title + " " + sum);
  }
  // console.log(sum);
  user.completion_percentage_of_all_projects = sum / user.projects.length;
  user.save();
};
exports.updateTasks = async (request, res) => {
  let id = request.body.id;
  let project = request.projectObject;
  // console.log(id);
  let planned = 0,
    wip = 0,
    review = 0,
    completed = 0;
  project.tasks.map(async (task) => {
    if (task._id.toString() === id.toString()) {
      task.taskName = request.body.taskName;
      task.taskDescription = request.body.taskDescription;
      task.pessimisticTime = request.body.pessimisticTime;
      task.optimisiticTime = request.body.optimisiticTime;
      task.mostLikelyTime = request.body.mostLikelyTime;
      task.status = request.body.status;
    }
    if (task.status === "PLANNED") planned++;
    else if (task.status === "WIP") wip++;
    else if (task.status === "Review") review++;
    else if (task.status === "COMPLETED") completed++;
    // console.log(task._id.toString(), id.toString());
  });
  let total_task = planned + wip + review + completed;
  let comp_percentage =
    (planned * 0 + wip * 0.33 + review * 0.66 + completed) / total_task;
  // console.log(comp_percentage*100);
  // console.log(request.body);
  project.completion_percentage = comp_percentage * 100;
  console.log("completion percentage:", project.completion_percentage);
  const users = [];
  project.save((err) => {
    if (err) return res.status(400).json({ err: "Task not found" });
  });
  await project.team.forEach((user) => {
    User.findById(user, (err, res) => {
      if (err) {
        res.status(400).json({ err: err });
      } else {
        updateUserCompletion(res);
      }
    });
  });
  // console.log(users);
  // console.log(request.body);
  return res.status(200).json({ project });
};

That is my code^

These are the outputs: supposed to be the same :(

2 of my users with 2 projects : user 1 user 2

2 projects linked with them : project 1 project 2

1 Answers

I can't guarantee it's the only problem, but one issue is this: To get a promise from findById, you have to use .exec. When using the promise, don't pass it a callback; instead, use the fulfillment value of the promise. So:

const sumItUp = async (project, sum) => {
    // console.log(project);
    const {completion_percentage} = await Project.findById(project).exec();
    sum += completion_percentage;
    console.log(`completion_percentage is ${completion_percentage}, updated sum is ${sum}`);
    return sum;
};
Related