angularngrxngrx-storengrx-reducers

ngrx update object inside array


I have a ngrx store with array of objects. What I am looking for is, update(modify) the object inside the array using the array index. My ngrx data will look like,

    policies: {
        beneficiaries: {
            beneficiaries: [{
                    name: 'pqr'
                    age: 56
                },
                {
                    name: 'xyz'
                    age: 76
                }
            ]
        }
    }

I have to update the beneficiary name based on the array index. So I have implemented the following reducer function

    on(policiesActions.updateBeneficiaryPercentage, (state, action) => {
        return {
          ...state,
          beneficiaries: {
            ...state.beneficiaries,
            beneficiaries: {
              ...state.beneficiaries.beneficiaries,
              [action.index]: {
                ...state.beneficiaries.beneficiaries[action.index],
                name: action.value
              }
            }
          }
        };
      })

The issue with the above code is that after running this code the structure of my store is changing to

policies: {
    beneficiaries: {
        beneficiaries: {
            0: {
                name: 'pqr'
                age: 1000
            },
            1: {
                name: 'xyz'
                age: 76
            }
        }
    }
}

Please help me to fix the code so that I can update the value without altering the store structure.


Solution

  • When updating an object in array, I would re-create an array with all excluded objects and append last object which needs updated value.

    const policies = {
      beneficiaries: {
        beneficiaries: [{
            name: 'pqr',
            age: 56
          },
          {
            name: 'xyz',
            age: 76
          }
        ]
      }
    }
    
    const updateObject = (state, action) => {
    
      if(!state.beneficiaries.beneficiaries[action.index]) {
        return state;
      }
    
      return {
        ...state,
        beneficiaries: {
          ...state.beneficiaries,
          beneficiaries: [
            ...state.beneficiaries.beneficiaries.slice(0, action.index),
            {
              ...state.beneficiaries.beneficiaries[action.index],
              name: action.value
            },
            ...state.beneficiaries.beneficiaries.slice(action.index + 1)
          ]
        }
      };
    }
    
    console.log(updateObject(policies, {index: 1, value: 'test'}))

    --Edit

    Added the snippet and changed the logic so it doesnt change list order.