Olubukola Ogunsola
Olubukola Ogunsola

Reputation: 25

New Object Property in React

I have an array of object i got from an API in a react app. the object has properties like name, email, city etc.Im trying to create a new propeerty, say age. i used the following code but react throws an error saying cant set property age of undefined. `

 addAge = (age, index) => {
    this.setState((prevState) => {
      let newData = Object.assign({}, prevState.newData);
      newData[index].age = age;
      console.log(newData);
      return { newData };
    });
  };`

please advice

Upvotes: 0

Views: 2666

Answers (2)

Matt Carlotta
Matt Carlotta

Reputation: 19762

A more standard practice is to update an object within array via an id (or something that is static and identifiable). This way, it ensures you're updating the correct object when/if the structure of the array happens to change -- from it being updated/changed via filters or new incoming data.

On a related note, you're switching the array to an object with Object.assign().

For example, this isn't want you want:

const target = [{ a: 1, b: 2 }, { a: 1, b: 2, c: 3}];

const returnedTarget = Object.assign({}, target);

console.log(returnedTarget);

Instead, you'll want to utilize Array.map and compare all of the objects ids with the passed in id.

const target = [{ id: 1, name: 2 }, { id: 2, name: 2 }];

const updateTarget = (id, newProp) => (
  // map over target and for each 'obj' check if the obj's 'id'
  // matches the passed in 'id'.

  // if equal (?) - spread out previous props, add new prop and return result
  // if not (:) - just return the obj as is
  target.map(obj => obj.id === id ? { ...obj, ...newProp } : obj)
);
    
    
const returnedTarget = updateTarget(2, { age: 42 });

console.log(returnedTarget);

Now just utilize the above example with your setState callback:

addAge = (id, age) => {
  this.setState((prevState) => (
    {
     // spread out previous state
     ...prevState, 
     // map over previous data...
     newData: prevState.newData.map(data => (
       // compare data object's id to passed in id
       data.id === id
         // if equal, add new prop to data object and return result
         ? { ...data, age }
         // else return data object as is
         : data
     ))
    }
  );
};

Upvotes: 1

hakisan_ks
hakisan_ks

Reputation: 46

Check out the document of Object.assign. It take in target and source objects then return an object.

// Your code here is trying to use index on the object so it return undefined because there is no key on your object that is a number.

newData[index].age = age;

You can fix this by removing the index. I recommend using spread operator instead:

const newData = {...prevState.newData, age}
return newData

Upvotes: 1

Related Questions