24

Assume there is an object:

const object = {
  'foo': {
    'bar': [1, 2, 3]
  }
}

I need to push 4 to object.foo.bar array.

Right now I'm doing it like this:

const initialState = Immutable.fromJS(object)
const newState = initialState.setIn(
  ['foo', 'bar', object.foo.bar.length],
  4
)
console.log(newState.toJS())

But I don't really like it, since I need to use object.foo.bar.length in the path. In my real example object is nested much deeper, and getting array's length looks very ugly. Is there another, more convenient way?

Alexandr Lazarev
  • 12,554
  • 4
  • 38
  • 47

2 Answers2

41

This should work

initialState.updateIn(['foo', 'bar'], arr => arr.push(4))

References:

Derek Adair
  • 21,846
  • 31
  • 97
  • 134
zerkms
  • 249,484
  • 69
  • 436
  • 539
  • Great! Thanks a lot! – Alexandr Lazarev Jul 27 '16 at 10:48
  • 3
    [arr.push](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push) is wrong, as it returns the /length/ of the new array. This will result in {foo: { bar: 3}}. You want to use [arr.concat](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat) – Derek Adair Apr 16 '19 at 16:15
  • 2
    `arr.push` is correct here but the naming is a little misleading: `arr` in his example is Immutable's List because OP created the state through `Immutable.fromJS`. `List.push` returns a new list with the argument(s) appended, so this does exactly what OP asked. – Steve Klösters Jul 30 '19 at 08:36
  • 1
    @PabloCG you're wrong, `push` here is not a `Array.prototype` method, but an immutablejs `List` method, which **DOES NOT** modify the original object. – zerkms May 27 '20 at 08:27
9

I'm using seamless-immutable, when I'm adding a new item to array of nested object, I got this error:

The push method cannot be invoked on an Immutable data structure.

My array still has push method, but it doesn't work. The solution is use concat instead, more details on #43:

initialState.updateIn(['foo', 'bar'], arr => arr.concat([4]));

Hope this help!

Huy Nguyen
  • 2,025
  • 3
  • 25
  • 37
  • Same issue here, makes sense since push modifies which isn't possible with immutable data structures. – Lucas Jan 20 '18 at 20:03