0

I am trying to do update an array "projects" depending on a query to a db forEach value from the array. When I get the value and assign it to the current index of the projects, it does not update on the actual array.

I've already tried some resolve reject promise structure, .map, .forEach, a normal for loop, a callback inside the query, but none of these have work.

projects.forEach((project, i) => {
    let query = squel
      .select()
      .field("s.Clave_Proyecto")
      .field("s.Semana_Numero")
      .field("s.Porcentaje_Semana")
      .from("Semana", "s")
      .where("s.Clave_Proyecto = ?", project["Clave_Proyecto"])
      .toParam();

    db.get().query(query.text, query.values, (error, weeks) => {
      if(error) return res.status(400).send(error);
      if(weeks) project["weeks"] = Object.values(JSON.stringify(weeks));
      else project["weeks"] = ["No weeks available"];

      projects[i] = project;
      console.log(projects[i]);
    });
});

It should return the project instance updated with the new "weeks" attribute as an array.

  • `Object.values(JSON.stringify(weeks)` is not likely correct. Maybe you meant `JSON.parse`? – Barmar Jun 19 '19 at 23:33
  • You're reusing the same `project` object every time through the loop. So all elements of the array contain the same project, and it contains the `weeks` value from the last iteration. – Barmar Jun 19 '19 at 23:37

1 Answers1

0

You need to create a new project object each time through the loop. Otherwise, you're setting all the array elements to reference to the same object, which is being overwritten each time.

You can use Object.assign() to clone the global object into a local variable.

    db.get().query(query.text, query.values, (error, weeks) => {
      if(error) return res.status(400).send(error);
      let tempProject = Object.assign({}, object);
      if(weeks) tempProject["weeks"] = Object.values(JSON.parse(weeks));
      else tempProject["weeks"] = ["No weeks available"];

      projects[i] = tempProject;
      console.log(projects[i]);
    });
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you so much for the reply, I really appreciate it. Just one thing, I tested your solution and it works fine partially. Once forEach loop is done, projects' array is still not updated; meaning that, each project still does not have the "weeks" attribute as expected. Surely I am doing something wrong:( – Oscar Rodriguez Jun 21 '19 at 18:49
  • Remember that this is asynchronous. You won't see the changes if you look immediately after the call, only in the callback function. – Barmar Jun 21 '19 at 19:10
  • See https://stackoverflow.com/questions/23667086/why-is-my-variable-undefined-after-i-modify-it-inside-of-a-function-asynchron – Barmar Jun 21 '19 at 19:10