Skip to content

Instantly share code, notes, and snippets.

@joeytwiddle
Last active November 12, 2019 08:14
Show Gist options
  • Save joeytwiddle/76d94d4cd45d247803286d73dd8a7b83 to your computer and use it in GitHub Desktop.
Save joeytwiddle/76d94d4cd45d247803286d73dd8a7b83 to your computer and use it in GitHub Desktop.
Getting properties from an object which might be null
// A common situation in Javascript:
//
// We have a variable `obj`, and we want to get `obj.foo.bar`
//
// But `obj` might be null or undefined, or `obj.foo` might be null or undefined
//
// So how can we try to get `obj.foo.bar` without risking an error?
// Here are a few different ways to do that. Which one is clearest?
// Note that the first way becomes longer if obj and foo have longer names, due to repetition
const result = obj && obj.foo && obj.foo.bar;
const result = ((obj || {}).foo || {}).bar;
const result = optional(optional(obj).foo).bar;
// where
function optional(obj) {
return obj == null ? {} : obj;
}
// Note that `obj == null` is a shortcut for `(obj === undefined || obj === null)`
// and is the only time `==` should ever be used!
// Instead of using the `optional()` function, you could use a similar function from
// one of these popular libraries:
// https://github.com/tc39/proposal-optional-chaining/issues/69#issuecomment-409045384
// We could have implemented `optional()` like this: `return obj || {};`
// That would match exactly the second inline method above.
// But the provided implementation is preferable because it allows falsey
// but non-empty values like 0 and false and '' to pass through
// In normal circumstances, if `obj.foo` is falsey, then:
//
// - The first method will return the falsey `obj.foo`, e.g. `0` or `false`
// - The second method will return `undefined`
// - The third method will return `undefined`
//
// If you are about to check `result` for truthiness, then it doesn't matter
// which method you use.
// Coffeescript and TypeScript (since 3.7) have the existential operator:
result = obj?.foo?.bar
const result = obj?.foo?.bar;
// And this has been proposed for Javascript too: https://github.com/tc39/proposal-optional-chaining
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment