31

According to the docs here: https://facebook.github.io/immutable-js/docs/#/Map/getIn

I should be able to get the deeply nested value by providing an array for the keyPath argument. This is what I've done, however I'm getting undefined as the return value.

http://jsfiddle.net/srxv4mwu/

var obj = Immutable.Map({categories: {1: 'a', 2: 'b'}});
var output = obj.getIn(['categories', 1]);
alert(output);

What am I doing wrong?

xiankai
  • 2,773
  • 3
  • 25
  • 31
  • Thank you for this question, why have the docs seemingly disappeared for `getIn` ? Has the method been deprecated? – SSH This Mar 02 '16 at 16:46
  • Sorry, apparently it's inherited: https://facebook.github.io/immutable-js/docs/#/Iterable/getIn – SSH This Mar 02 '16 at 17:20

2 Answers2

57

A map is simply a collection of keys with values. What you have is a map with the key categories, and the value {1: 'a', 2: 'b'}. The value does not automatically become an Immutable map just because you place it inside another map.

Now, the getIn() function will only "see" other Immutable.js maps. What you have in there is a regular ol' javascript object. If you just want to get the 1 value, you can just do:

var obj = Immutable.Map({categories: {1: 'a', 2: 'b'}});
var output = obj.getIn(["categories"])[1];
alert(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.min.js"></script>

If you want the categories collection to also be a map, you'll have to define that explicitly. Also, as Amit pointed out, you'll need to use strings with the getIn() function.

var obj = Immutable.Map({
 categories: Immutable.Map({
  1: 'a',
  2: 'b'
 })
});
var output = obj.getIn(['categories', '1']);
alert(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.min.js"></script>

The above code will return 'a'.

It would probably be more convenient for you to do something like below, if you have many nested maps.

var obj = Immutable.fromJS({
 categories: {
  1: 'a',
  2: 'b'
 }
});
var output = obj.getIn(['categories', '1']);
alert(output);
<script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.min.js"></script>

The fromJs() function will convert any nested objects into maps or lists automatically for you.

Yonggoo Noh
  • 1,811
  • 3
  • 22
  • 37
user1440308
  • 832
  • 8
  • 9
  • Now the snippets work. The Immutable libraries weren't linked before. – Carsten Massmann Jul 02 '17 at 16:42
  • "Now, the getIn() function will only "see" other Immutable.js maps. What you have in there is a regular ol' javascript object...." I posted a question related to this at https://stackoverflow.com/questions/49025635/deep-access-in-plain-objects-with-immutable The documentation quoted there seems to indicate that plain objects are also supported with getIn ? – davidkomer Feb 28 '18 at 10:18
18

There are 2 problems with your code:

  1. Immutable.Map(...) doesn't traverse the parameter to create a complex immutable. For that you need Immutable.fromJS(...).
  2. Once you do that, you need to use strings in getIn(...), so ['categories', '1'] instead of ['categories', 1].

See working fiddle.

Fábio Batista
  • 25,002
  • 3
  • 56
  • 68
Amit
  • 45,440
  • 9
  • 78
  • 110