Reputation: 5220
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
});
};
}
Upvotes: 3
Views: 2182
Reputation: 1445
I have created lithe example on link to solution on jsbin.com
const initialState = Immutable.Map({
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'})
])
});
console.log('initialState', initialState.toJS())
// update lines, map over items and set active to false
const stateLinesAllNotActive = initialState.updateIn(
['lines'],
items => items.map((item) => item.set('active', false))
)
console.log('stateLinesAllNotActive', stateLinesAllNotActive.toJS())
// lines and key for item with id === 1, then set active to this item
const stateFirstActive = stateLinesAllNotActive.updateIn(
[
'lines',
stateLinesAllNotActive.get('lines').findIndex((item) => (item.get("id") === 1))
],
item => item.set("active", true)
)
console.log('stateFirstActive', stateFirstActive.toJS())
Upvotes: 1
Reputation: 14216
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.
Upvotes: 2
Reputation: 14169
What follows should work, but, as someone said... I think could be better a full update...
const initialState = Immutable.Map({
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'})
])
});
let lines = initialState.get('lines');
let id = 1; // what you want update...
let updater = item => {
let updated = item.set('name', "Giuseppe");
return updated;
};
let index = lines.findIndex((i) => i.get("id") === id);
let result = lines.update(index, updater);
initialState.set("lines", result);
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.js"></script>
Upvotes: 0