axtck
axtck

Reputation: 3965

Update object property values and push them into array in for loop

I am trying to update properties on an object while looping through the new values and pushing them into an array, I am a bit confused on how to do this. I would like to start from a default object on which only some of the property values need to get changed.

I created 2 arrays with new values to update the default object with, when I log the updated person separately console.log(defaultPerson), the output I expected gets printed (the person with updated name and hair color). I expected that pushing the updated person into an array at the end of the loop would push the value that gets printed when logging.

// the default object
const defaultPerson = {
  name: "default",
  address: "Some street",
  hair: {
    color: "default",
  }
}

// new values to update
const newNames = ["Alexander", "Hendrik", "Stephan"];
const newHairColors = ["brown", "brown", "black"];

const updatedPeople = []; // array for updated people

for(let i = 0; i < newNames.length; i++) {
  defaultPerson.name = newNames[i];
  defaultPerson.hair.color = newHairColors[i];
  
  console.log(defaultPerson); // logs the updated object
  updatedPeople.push(defaultPerson); // pushes last values 3 times
}

console.log("Print array");
updatedPeople.forEach(p => console.log(p));

This does not seem to be the case, instead the values inside the array are 3 times the object updated with the last value from the new values array (Stephan, black).

I figured creating a new object inside the loop and setting it equal to the spread default object and then update its values could be a solution. That way every loop, a new object is created and gets its values updated before pushing it in the array. This works, but only on the name value of the person, hair.color still stays the same, this is probably because hair is another nested object and so it goes on.

// the default object
const defaultPerson = {
  name: "default",
  address: "Some street",
  hair: {
    color: "default",
  }
}

// new values to update
const newNames = ["Alexander", "Hendrik", "Stephan"];
const newHairColors = ["brown", "brown", "black"];

const updatedPeople = []; // array for updated people

for (let i = 0; i < newNames.length; i++) {
  const newPerson = { ...defaultPerson }; // spread
  newPerson.name = newNames[i];
  newPerson.hair.color = newHairColors[i];

  updatedPeople.push(newPerson);
}

updatedPeople.forEach(p => console.log(p));

Upvotes: 0

Views: 1923

Answers (1)

Heretic Monkey
Heretic Monkey

Reputation: 12112

Rather than pushing, I'd just map the array of names into an array of "person" objects. Note that this works only because newHairColors has the same length as newNames.

// the default object
const defaultPerson = {
  name: "default",
  address: "Some street",
  hair: {
    color: "default",
  }
}

// new values to update
const newNames = ["Alexander", "Hendrik", "Stephan"];
const newHairColors = ["brown", "brown", "black"];

const updatedPeople = newNames.map((newName, i) => ({
   ...defaultPerson,
   name: newName,
   hair: {
      ...defaultPerson.hair,
      color: newHairColors[i]
   }
}));

updatedPeople.forEach(p => console.log(p));

Upvotes: 1

Related Questions