Michal Jarnot Michal Jarnot - 4 months ago 15
Javascript Question

How to change property of item in ImmutableList({}) inside Immutable.Map({})

How do I change property of item in

ImmutableList({})
that is inside
Immutable.Map({})
?

I have:

const initialState = Immutable.Map({
width: window.board.width,
height: window.board.height,
lines: Immutable.List([
Immutable.Map({id: 1, active: false, name: 'Some name'}),
Immutable.Map({id: 2, active: false, name: 'Sad name'}),
Immutable.Map({id: 3, active: true, name: 'Cool name'})
])
});


Lets say I want to set item with
id
1 in the List. Then change its property active to true. I also want to set property active to false for all the other items in the List.

How do I do that? Thanks a lot in advance.

Edit (final solution):

export function activateLine(lineId) {
return function (dispatch, getState) {
const updatedLines = getState().board.update('lines', Immutable.List(),
(oldList) => oldList.map((listItem) => {
return listItem.set("active", (listItem.get("id") === lineId));
})).get('lines');

return dispatch({
type: types.ACTIVATE_LINE,
payload: updatedLines
});
};
}

Answer

You can traverse immutable like so (quick note though i would highly recommend you make the entire object immutable). You can keep down the lines of code and keep it a bit more elegant by just using immutable itself -

const changeImmutableObject = initialState.update('lines', Immutable.List(),
    (oldList) => oldList.map((listItem) => {
        if(listItem.get("id") === 1) {
            return listItem.set("active", true);
        } else {
            return listItem.set("active", false);
        }
    })
  )

See working fiddle - https://jsfiddle.net/o04btr3j/214/

This updates the list key inside your object (if it is not there for whatever reason it defaults to an immutable list), then maps over the properties. If it has an id of 1, it will set active to true, otherwise it will set active to false.

You can also just initialState.toJS() your immutable object and do your logic in plain js, or do and immutableobject.get('property') and modify and then set that back in your object, however I would recommend you just use the built in methods in immutable as it is much less code.

Also, If I'm not mistaken you can just do something like this :

const initialState = Immutable.fromJS({
width: window.board.width,
height: window.board.height,
lines:[
    {id: 1, active: false, name: 'Some name'},
    {id: 2, active: false, name: 'Sad name'},
    {id: 3, active: true, name: 'Cool name'}
]
});

You can immutable.fromJS() an object to put it into an immutable object. And all immutable objects should have a .toJS method on them to turn them back into regular javascript objects/lists/whatever.

Comments