3

For deeply nested property access, is there a JS operator similar to the "optional chaining" operator which applies to all properties/methods/etc. to the right?

Consider an object with deep nesting, where some properties are null:

const sort = payload.meta.displayConfig.properties.search.sort;
//                        ^---null?     ^---null?  ^--null?

This can be handled with the optional-chaining operator:

const sort = payload.meta.displayConfig?.properties?.search?.sort;

But is there another operator where "all calls to the right" are handled as if they were preceded by the optional-chaining operator? Observe:

const sort = payload.meta.displayConfig?!.properties.search.sort;
//                                     ^^---fictional nested-optional-chaining 
//                                          operator

In this example (with the fictional ?! nested-optional-chaining operator), if anything from displayConfig and onward to the right (properties, search) are null or undefined, then execution is short-circuited as if each property was preceded by ?.

Is there any discussion around adding such a feature?

Josh M.
  • 26,437
  • 24
  • 119
  • 200
  • Is this the same as null coalescing or am I misunderstanding? `foo?.bar?.bizz?.world ?? "hello"`. Maybe compare with [Is there a “null coalescing” operator in JavaScript?](https://stackoverflow.com/q/476436/691711). – zero298 Nov 11 '20 at 19:44
  • 1
    Sounds like you need something like the `Maybe`/`Optional` monad. Once something is a Maybe (think "nullable") it stays like this throughout all operations. – VLAZ Nov 11 '20 at 19:57
  • 1
    @zero298 no, I think OP just wants something that essentially automatically makes all property access into optional chaining from a given point. Imagine transforming `a.b.c?!.d.e.f` into `a.b.c?.d?.e?.f`. – VLAZ Nov 11 '20 at 20:01
  • @VLAZ That's correct. Just a shorthand for optional-chaining multiple properties. – Josh M. Nov 13 '20 at 16:55

1 Answers1

5

The short answer is no. You have to put ?. between each segment if you want to make each segment safe against null/undefined values. And as far as I can tell from looking through the different proposals for ecmascript there hasn't been any discussion of an operator like you're talking about.

Before the optional chaining operator was a thing, many libraries would implemented their own ways to get an attribute in a safe way, some of which behave closer to what you're wanting. For example, in lodash you can do _.get(payload, 'meta.displayConfig.properties.search.sort') However, now that the optional chaining operator is a thing, I would prefer just using it between every segment instead of using these library functions.

Update

I should mention that if you find yourself commonly needing to place ?. between each segment, without exception, it's possible you don't quite understand the short-circuiting nature of the ?. operator.

If I have some large object, and I want to access a deeply nested property from it, but it's possible that this whole object might really be a null value, I only need one ?., like this: user?.addresses.preferredAddress.street. I don't have to do user?.addresses?.preferredAddress?.street.

In general, it's fairly rare to have a data structure where every single property on it could potentially be null or undefined, and you must place a ?. between every segment. Even if such a data structure did exist, it would generally behave like that "by chance", rather than some inherent nature of the data structure, and because of that, I'd argue that it's better to place a "?." between each segment to explicitly document at each step that "yes, I expect that this specific property could be null/undefined".

There's likely exceptions to this all, but such exceptions should (hopefully) be fairly rare.

Scotty Jamison
  • 10,498
  • 2
  • 24
  • 30
  • I agree, I wouldn't use lodash's `get` because it relies on non-type-safe strings. Thanks for your input. – Josh M. Nov 11 '20 at 20:15