Home > database >  Change values of array of objects for provided ids
Change values of array of objects for provided ids

Time:08-21

how can i change the values of provided ids ? i keep getting this TypeError: Cannot set properties of undefined (setting 'select')

  const data = [
   {
    id: 1,
    select: false
   },
   {
    id: 2,
    select: true
   },
   {
   id: 3,
   select: true
   },
   {
   id: 4,
   select: false
   },
   {
   id: 5,
   select: false
   }
   ];
   const ids = [1, 2, 4];

   let d = [...data];
   for (let i = 0; i < d.length - 1; i  ) {
   const objIndex: number = d?.findIndex((obj: any) => obj.id === ids[i]);
  d[objIndex].select = true;
  console.log(d);
  }

i want to change the boolean values of provided ids and make a new data object (same data but changed boolean values of provided ids) Need Help !enter image description here

CodePudding user response:

Perhaps instead of searching in the data for specific ID, search in the list of ids, it makes it simpler and depending on size of data and number of ids it might be even faster:

const data = [
   {
    id: 1,
    select: false
   },
   {
    id: 2,
    select: true
   },
   {
   id: 3,
   select: true
   },
   {
   id: 4,
   select: false
   },
   {
   id: 5,
   select: false
   }
   ];
   const ids = [1, 2, 4];

   for (let i = 0; i < data.length; i  ) {

   if (ids.includes(data[i].id))
    data[i].select = true;
   
  }
  console.log(data);

CodePudding user response:

You are iterating through d array and you're trying to access ids array with an index that does not point to any value in this array. So .findIndex is returning -1, and when you try to access it in d[objIndex] it is also undefined there because there is no element with that index.

In order to fix your code you would have to iterate first through ids array to get indices of objects with exact ids and then use that index to change the value.

Fixed code:

  const data = [
   {
    id: 1,
    select: false
   },
   {
    id: 2,
    select: true
   },
   {
   id: 3,
   select: true
   },
   {
   id: 4,
   select: false
   },
   {
   id: 5,
   select: false
   }
   ];
   const ids = [1, 2, 4];

   let d = [...data];
   ids.forEach((id) => {
       const objIndex: number = d?.findIndex((obj: any) => obj.id === id);

       // safe guard if there is no object with that id
       if (objIndex === -1) {
           return;
       }

       d[objIndex].select = true;
   })

CodePudding user response:

Your current for loop is doing d.length-1 iterations, so i will go out of the valid index ranges for indexes in ids. As a result, when you try and do ids[i] on a value of i that isn't an index in ids you get back undefined, which ends up with the .findIndex() being unable to find an object as there is no object that has an undefined id property. This causes the next line of code to crash as it tries to update an object in your array that doesn't exist. For your code to work your condition should be i < ids.length;.

However, assuming that data is a state value (which I've gathered here as you've tagged this as and you've cloned your data array), you shouldn't be modifying your object within data like you currently are. The main problem is that const d = [...data] only does a shallow copy of your array, so your objects are still references, which means you're modifying your state directly when you do d[objIndex].select = true which can cause issues with rerendering.

To resolve that, you could do a deep clone of your array, or instead, use .map() on your data and return a new object if it needs to be updated as shown below. The below uses the spread syntax (...) to create a new object with all the properties of the current object if its id is in ids, and then we overwrite the value of select to update it to true:

const data = [{ id: 1, select: false }, { id: 2, select: false }, { id: 3, select: false }, { id: 4, select: false }, { id: 5, select: false } ];
const ids = [1, 2, 4];

let newData = data.map(obj => ids.includes(obj.id) ? {...obj, select: true} : obj);
console.log(newData);

  • Related