Reputation: 4045
My state is a nested Immutable thing:
const state = Map({ counter: 0,
people: List([
Map({name: "John", age: 12, etc...}),
Map({name: "Jim", age: 13, etc...}),
Map({name: "Jack", age: 21, etc...})
])
});
So I have a Map, which holds a counter and List of Maps. I have simplified things here, but say I want to change some properties of John in my reducer.
Right now I'm doing something like this:
var newState = state
.get('people') //get the list
.get(action.payload.pos) //pos is an integer, & describes the position of the object in the List
.set('name', action.payload.name)
.set('age', action.payload.age);
My problem is that I don't know how to set properties in John and get back the whole state, - so I can return it in my reducer. Right now what I am getting back is only the very part I am changing.
A second problem is this very long way to write all of this down. I know that there is a syntax for nested structures, but I have a List
here, which kind of breaks this, so I am a bit stuck.
Upvotes: 1
Views: 376
Reputation: 5000
You can use .findIndex
to find the index to update (if you don't already have it), and then use the index in a .updateIn
call, together with .merge
to merge the old and the new values.
const state =
new Immutable.Map({
counter: 0,
people: new Immutable.List([
new Immutable.Map({name: "John", age: 12, otherVal: 'a'}),
new Immutable.Map({name: "Jim", age: 13, otherVal: 'b'}),
new Immutable.Map({name: "Jack", age: 21, otherVal: 'c'})
])
});
const newValues = { name: 'Jones', age: 100};
// find index to update
const indexToUpdate = state
.get('people')
.findIndex(person => person.get('name') == 'Jim');
// use .updateIn to perform a merge on the person of interest
const newState =
state.updateIn(
['people', indexToUpdate],
person => person.merge(newValues)
);
console.log(
'new state is:\n',
JSON.stringify(newState.toJS(), null, 2)
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.7.2/immutable.min.js"></script>
Upvotes: 2