immutable-js-oss / immutable-js

Immutable persistent data collections for Javascript which increase efficiency and simplicity.
https://immutable-js-oss.github.io/immutable-js/
MIT License
37 stars 6 forks source link

functional get, getIn is not working with class collections (like es6 Map) #125

Open Methuselah96 opened 4 years ago

Methuselah96 commented 4 years ago

From @Monar on Thu, 31 Jan 2019 21:41:41 GMT

What happened

We cant create class which will work with functional get, getIn. Ok we can by extending our class with immutable base to make it pass isImmutable but if our class is not 100% "isImmutable" compatible... Is this intentional?

import { get } from 'immutable';
class TestCollection {
  constructor() { 
    this._root = { 'fizz': 'buz' };
    this.other = 'yeah';
  };
  get(key) { return this._root[key] }
}
let test =  new TestCollection()
get(test, 'fizz') // undefined 
get(test, 'other') // undefined 

Also implementation of get is a little bit convoluted, making me think that this limitation was not intentional.

Let check get and has (has is only only used by get). What makes it not work with es6 Map collection :(

// get
return isImmutable(collection)
    ? collection.get(key, notSetValue)
    : !has(collection, key) // [1]
      ? notSetValue // [2]
      : typeof collection.get === 'function' // [3]
        ? collection.get(key) // [4]
        : collection[key]; 

Solution ?

If get should work with class collections implementing get method then we can do something like this:

export function get(collection, key, notSetValue) {
  return isImmutable(collection)
    ? collection.get(key, notSetValue)
    : typeof collection.get === 'function'
        ? collection.get(key, notSetValue)
        : hasOwnProperty.call(collection, key)
            ? collection[key]
            : notSetValue;
}

Copied from original issue: https://github.com/immutable-js/immutable-js/issues/1688