Home > other >  How to update Map object in state in ngrx
How to update Map object in state in ngrx

Time:12-02

I have a property in my state which is Map<string, object | 'error'> . When I get response from service I wish to update this map. I have tried below in the reducer

 on(setMapData, (state, action) => {    
    const { data } = action  
    data.forEach( (value, id) => {
      let dataMap = state.dataMap
      dataMap.set(id, value)
      return {
        ...state,
        dataMap: {...state.dataMap, ...dataMap}
      }
    }) 
//Till here I can see dataMap having all the values in state.
    return {
      ...state
      //dataMap: state.dataMap
    }
// But nothing is returned from here, my selectors are not getting invoked.
  })

Below is my state object

export const initialState: dataState = {
  loading: true,
  dataMap: new Map<string, object | 'error'>()
}

Please help me in this issue. Thanks in advance.

CodePudding user response:

I can think of two solutions :

  1. Use Immer or ImmutableJs to generate a copy of Map at the reducer and then update the values. for example using immer your code code be something like this:

on(setMapData, (state, { data }) => {

    //Create a deep copy of the state dataMap and update it
    let dataMap = produce(state.dataMap, newData => {
        //loop through the received Map and get the new key,value pair
        data.forEach((value, key) => {
            //Set the new key, value pair of the map to the copied Map
            newData.set(key, value)
        });
    });

    //return the state with the new Map
    return { ...state, dataMap };
});
  1. and I think this is the safest way: Your use case above is similar to what ngrx-entity offers. Try to not re-invent the wheel this package will help you update your map without worrying about the state (entities are Map) using their predefined methods.

CodePudding user response:

i can tell you, that using a Map-Object in an Action wont work. It will always show as empty. I dont exactly know why this is, but i believe the reason is, a Map is a Mutable-Object. Ngrx doesnt handle those at all. If you for exmaple use immutableJS on a Map, it would create a new Map().

Sorry for only half the answer.

  • Related