Daryn
Daryn

Reputation: 3768

Immutable JS - merge creates a list of map objects from array

I am using redux and immutablejs, and I am trying to create a reducer function.

I have come across some behaviour I did not expect

const a = new Immutable.Map({
  numbers: [{id: 1},{id: 2}]
});

const b = a.merge(
  {
    numbers: [{id: 4},{id: 5}]
  }
);

Here are the values of a and b

a.get("numbers");
[Object, Object]
b.get("numbers");
List {size: 2, _origin: 0, _capacity: 2, _level: 5, _root: null…}
b.get("numbers").get(0);
Map {size: 1, _root: ArrayMapNode, __ownerID: undefined, __hash: undefined, __altered: false} 

I did not expect numbers to be an immutable List of Map objects.

In my application, using redux, I set the initial state to:

const initialState = new Immutable.Map({
  error: null,
  isBusy: false,
  films: []
});

I the reducer, when I fetch films I try to merge them as follows:

return state.merge({
        isBusy: false,
        films: action.payload,
        error: null
      });

This causes issues in the react component, as films are initially an array of objects, and then they become an Immutable List of Maps.

Should I create a different initial state, or should I be using a different type of merge? Or something else?

Thanks

Upvotes: 3

Views: 2136

Answers (1)

erdysson
erdysson

Reputation: 1480

I think what you are trying to do is not merge of whole map object, at least should not be in the case you say, it should be update + ( concat or merge ):

const a = new Immutable.Map({
  numbers: [{id: 1},{id: 2}]
});

const b = a.update("numbers", numbers =>
  numbers.concat([{id: 4},{id: 5}])
  // or
  numbers.merge([{id: 4},{id: 5}])
);

by doing merge in your code, you are overriding the existing ones due to the nature of "merge" because the keys are the same in the merge; "numbers".

Upvotes: 2

Related Questions