ArunValaven
ArunValaven

Reputation: 1969

How to deep update two values inside Immutable Js Map in redux?

I am trying to update two(width & x) values inside items -> yrgroih9 as given below:

{
  appElements: {
    layers: {
      layer_1: {
        background: {
          width: '100px',
          height: '100px',
          bgColor: '#aaaaaa',
          bgImage: 'http:bgimage1.png'
        },
        items: {
          yrgroih9: {
             width: '100px',
             x: '200px',
             y: '200px'
           },
           qhy0dukj: {
             width: '100px',
             x: '200px',
             y: '200px'
           },
           '7lw2nvma': {
             width: '100px',
             x: '200px',
             y: '200px'
           }
        }
      }
    }
  }
}

Code used to update new object inside items-> yrgroih9:

case 'UPDATE_OBJECT':
  return state.setIn(["appElements","layers","layer_1","items","yp57m359"],{
    ["width"]: action.objData.width,
    ["x"]: action.objData.x
  });

The above code removes y key inside the current location yrgroih9 and updates the width and x values.

Redux store data arranged after setIn: (from chrome redux devtools): enter image description here

How to update two deep values without removing the other key values.?

Upvotes: 5

Views: 2820

Answers (2)

Misha
Misha

Reputation: 6576

Use updateIn.

If your items are instances of Immutable.js Map:

case 'UPDATE_OBJECT':
  return state.updateIn(['appElements', 'layers', 'layer_1', 'items', 'yrgroih9'],
    (item) => item
      .set('width', action.objData.width)
      .set('x', action.objData.x)
  );

If your items are plain JS objects:

case 'UPDATE_OBJECT':
  return state.updateIn(['appElements', 'layers', 'layer_1', 'items', 'yrgroih9'],
    (item) => ({
      ...item,
      width: action.objData.width,
      x: action.objData.x,
    })
  );

Upvotes: 5

Hypuk
Hypuk

Reputation: 244

state.setIn replace the whole object in the path you have given (appElements -> layers -> layer_1 -> items -> yp57m359). You can get an existing object, modify fields and then use setIn:

const oldObject =
 state.hasIn(["appElements","layers","layer_1","items","yp57m359"])
   ? state.getIn(["appElements","layers","layer_1","items","yp57m‌​359"])
   : {};
const newObject = {
  ...oldObject,
  width: action.objData.width,
  x: action.objData.x
};
return state.setIn(["appElements","layers","layer_1","items","yp57m359"], newObject);

Upvotes: 0

Related Questions