Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot access properties of Immutable.js map

I use Immutable.js to deserialize stored maps. Unfortunately I have not yet managed to access properties of the map. If I run the code like below, I get the right map entry. If I try to access the property name, I get an undefined object. I'm new to JS and haven't quite figured out how to access the entries yet.

I get this object back if I run the following code. How can I access the name now?

let map: Immutable.Map<string, User> = Immutable.fromJS(users[index].userMap).toMap();
console.log(map.get("4");
Map {size: 2, _root: ArrayMapNode, __ownerID: undefined, __hash: undefined, __altered: false}
  size: 2
  _root: ArrayMapNode
    ownerID: OwnerID {}
    entries: Array(6)
      0: (2) ["name", "joe"]
      1: (2) ["text", "test"]
      length: 2
      __proto__: Array(0)
  __proto__: Object
  __ownerID: undefined
  __hash: undefined
  __altered: false
  state: true
__proto__: KeyedCollection

User

export interface User {
  name: string;
  text: string;
}
userMap: Immutable.Map<string, User>;
like image 763
laprof Avatar asked Jun 03 '26 09:06

laprof


1 Answers

Issues with access

Using typescript tricked you into thinking that that map actually contains User. It does not. Immutable.fromJS deeply converts objects to maps, unless the objcts are Immutable objects (e.g. Map, List, Record,...).

You even saw it when console.log(map.get("4")); returned an Immutable.Map.

So to access it, treat them like nested maps: map.getIn(["4", "name"]); Or convert the Users to Immutable.Records before adding them to the map:

const UserRecord = Record({ name: undefined, text: undefined });
Immutable.Map(users[index].userMap.map(entry => UserRecord(entry));
console.log(map.get("4").name);

Issues with modification

It's working now with map.getIn(["4", "name"]);, but I cannot use setIn(["4", "name"], "newName"). it just won't update the name.

You might not have fully understood how immutable works. Immutable objects never change (that's the whole point!). map.setIn(["4", "name"], "newName") will not change anything, it returns a new map that contains the updated data! You would have to assign it to something to see the updated data, e.g.

const changedMap = map.setIn(["4", "name"], "newName");
like image 170
dube Avatar answered Jun 06 '26 00:06

dube



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!