Sourabh Banka
Sourabh Banka

Reputation: 1117

Change value of a key in array of objects in redux reducer

My array is like this:

var arrayObj = [{key1:'value1', key2:'value2'},{key1:'value1', key2:'value2'},{key1:'value1', key2:'value2'},{key1:'value1', key2:'value2'},{key1:'value1', key2:'value2'}];

I am sending index, key and value.

Suppose if I will send (2, 'key2', 'hello') then reducer update the above array as:

var arrayObj = [{key1:'value1', key2:'value2'},{key1:'value1', key2:'value2'},{key1:'value1', key2:'hello'},{key1:'value1', key2:'value2'},{key1:'value1', key2:'value2'}];

All the data are comming in action.payload. I have tried something like this:

 return {
   ...state,
   arrayObj: [
    ...state.arrayObj.slice(0, action.payload.arrayObjIndex),
    ...state.arrayObj[action.payload.arrayObjIndex]: {
      ...state.arrayObj[action.payload.arrayObjIndex],
      [action.payload.key]: action.payload.value,
    },
    ...state.arrayObj.slice(action.payload.arrayObjIndex + 1),
   ],
  };

But the above one is not working.

Upvotes: 4

Views: 3760

Answers (2)

Mayank Shukla
Mayank Shukla

Reputation: 104369

Issue with the code - Remove the ... from the object that you are updating, because you need to spread the array (returned by slice), not object. Use this:

 return {
   ...state,
   arrayObj: [
    ...state.arrayObj.slice(0, action.payload.arrayObjIndex),
    {
      ...state.arrayObj[action.payload.arrayObjIndex],
      [action.payload.key]: action.payload.value,
    },
    ...state.arrayObj.slice(action.payload.arrayObjIndex + 1),
   ],
};

Suggestions/ Other possible solutions:

If you know the index then you can directly update the object, like this

case "String" : {
  let arr = [...state.arrayObj]
  arr[index] = {...arr[index]}        // Object.assign({}, arr[index])
  arr[index][key] = value
  return {
    ...state,
    arrayObj: arr
  }
}

Or

case "String" : {
  let arr = [...state.arrayObj]
  arr[index] = {...arr[index], [key]: value}     // Object.assign({}, arr[index], {[key]: value})
  return {
    ...state,
    arrayObj: arr
  }
}

You can use map also or findIndex, if index of the item is not known, check this answer for that:

Update single value of array in redux reducer

Upvotes: 4

Sagar Jajoriya
Sagar Jajoriya

Reputation: 2375

You can do this by :

let prevState = {...state};

prevState.arrayObj[action.payload.arrayObjIndex][action.payload.key] = action.payload.value;

return prevState;

Upvotes: 0

Related Questions