Nullish Coalescing Operator '??'
Published July 2nd, 2021 • ☕ 2 min read
Can you recognize yourself in one of the following snippets you? If yes, hang tight, because we will look at a better way to provide fallbacks right after.
1. Override variable, if it's undefined
or null
let val = getValueFromApiRequest();if (val === null || val === undefined) {val = "fallback value";}doSomethingWith(val);
This can be slightly shortened:
let val = getValueFromApiRequest();doSomethingWith(val === null || val === undefined ? "fallback value" : val);// or switching the order of the logic (but basically the same thing):doSomethingWith(val !== null && val !== undefined ? val : "fallback value");
The Nullish Coalescing Operator cannot be used on a non-declared root object, but can be used
with an undefined root object. Hence we are declaring let val
before in some way:
let val = getValueFromApiRequest();
2. Using lodash.defaultTo
(or lodash.get
for object properties)
Note, that _.defaultTo
will return the fallback if the value is undefined
, null
, or NaN
. On the other hand, _.get
will only return the fallback, if the property is undefined
. If it's null
, null
will be returned.
import defaultTo from "lodash.defaultTo";import get from "lodash.defaultTo";// or alternatively:// import defaultTo from 'lodash/defaultTo';// import get from 'lodash/get';let val = getValueFromApiRequest();doSomethingWith(defaultTo(val, "fallback value"));// or for object properties:doSomethingWith(get(val, "some.property", "fallback value"));
3. Check only for "truthy" (or "falsy")
Often enough it's sufficient to just check very shallowly for a falsy value. That means, that the fallback will be used if the value is either false
, 0
, -0
, 0n
, ""
, null
, undefined
, or NaN
(the other way around, a truthy value is none of those).
let val = getValueFromApiRequest();if (!val) {val = "fallback value";}doSomethingWith(val);
There is slightly shorter variations of this, too:
let val = getValueFromApiRequest();doSomethingWith(val || "fallback value");// ordoSomethingWith(val ? val : "fallback value");// ordoSomethingWith(!val ? "fallback value" : val);
This is usually safe to use and probably the most common fallback check of all. It will only lead to issues, if the passed values are actually valid arguments in the used function.
For example, the following example would cause unwanted behavior, which would be really hard to find (because there is no syntactical error):
const add = (a, b) => {return a + b;};let val1 = 7,val2 = 0;const doSomething = () => {// 0 is falsy, and so the program will execute// the code in the else-clauseif (val1 && val2) {return add(val1, val2);} else {return add(1, 2);}};doSomething();// => 3
The better way to provide fallback values in JavaScript
In December 2019, the TC39 proposal for the Nullish Coalescing Operator (??
) has reached stage 4 (which means finished and ready to be included into EcmaScript). Node.js >= 14 supports it as well as ~87% of today's used browsers.
If you have to support older browsers or are not yet on newer Node.js versions, you can use @babel/plugin-proposal-nullish-coalescing-operator
to transpile your code (every occurrence of it will bloat the bundle size a little, but that's practically irrelevant in most cases).
Anyway, we can close the loop here, as the Nullish Coalescing Operator simply is an actual shortcut for the first and most explicit fallback check which we learned earlier: Checking for undefined
or null
.
let val = getValueFromApiRequest();// Now, instead ofdoSomethingWith(val !== null && val !== undefined ? val : "fallback value");// we can write:doSomethingWith(val ?? "fallback value");
That's pretty much the conveniently simple gist. If you like, you can read up on caveats like precedence here.