rtfeldman / seamless-immutable

Immutable data structures for JavaScript which are backwards-compatible with normal JS Arrays and Objects.
BSD 3-Clause "New" or "Revised" License
5.37k stars 194 forks source link

getIn() for safe deep access #149

Closed geirsagberg closed 7 years ago

geirsagberg commented 7 years ago

Coming from Immutable JS, loving seamless-immutable, but have one issue when I want to access an object deep in the state graph, that may or may not exist, e.g.

var foo = state.bar.baz.foo || ''; // will fail if bar or baz is null

Would be awesome to have something like getIn from ImmutableJS:

var foo = state.getIn(['bar', 'baz', 'foo'], ''); // Will return '' if bar or baz is null
crudh commented 7 years ago

Using lodash works fine otherwise:

import _get from 'lodash/get';

const foo = _get(state, 'bar.baz.foo', '');
geirsagberg commented 7 years ago

Thanks for the tip, will use that as a workaround!

However, if seamless-immutable had a native getIn, the syntax would be more consistent with setIn etc, and we could also automatically wrap the fallback value as an Immutable.

guyellis commented 7 years ago

If you want to keep the getIn syntax then building on @crudh idea create a utility method.

import _get from 'lodash/get';

function getIn(state, path, alt) {
  return _get(state, path.join('.'), alt);
}

var foo = getIn(state, ['bar', 'baz', 'foo'], '');

Might make transition from ImmutableJS easier and keeps syntax similar to what might be implemented in seamless.

zackify commented 7 years ago

Dang, this was the big thing I was excited about. I was hoping doing state.bar.baz would return undefined if bar didn't exist. I guess that can only be accomplished by using a proxy, which isn't in IE11, so it isn't feasible for me.

renatorib commented 7 years ago

@zackify there is a proposal for this feature called Null Propagation (or Optional Chaining, or Existential Operator, or Null-safe property access) https://github.com/claudepache/es-optional-chaining

// today
const street = user && user.address && user.address.street

// proposal
const street = user?.address?.street;
geirsagberg commented 7 years ago

Looks like https://github.com/rtfeldman/seamless-immutable/pull/188 is released, closing this.