This blog post shows how you can conditionally add elements inside Array literals and properties inside object literals.
The following code shows how a boolean cond determines whether or not the element 'a' is added to the Array arr.
const cond = false;
const arr = [
...(cond ? ['a'] : []),
'b',
];
// ['b']
This trick works, because the spread operator (...) for Array literals does nothing if its operand is an empty Array:
> [...[], 'a']
[ 'a' ]
You can use the proposed spread operator for properties in the same manner. Again, a boolean cond determines whether the property a is added to the object obj:
const cond = false;
const obj = {
...(cond ? {a: 1} : {}),
b: 2,
};
// {b: 2}
The spread operator for object literals does nothing if its operand is an object without enumerable own properties:
> {...{}, a: 1}
{ a: 1 }
Using the spread operator in this manner leads to slightly cryptic code. Here it is again, for ease of reference:
const arr = [
...(cond ? ['a'] : []),
'b',
];
The crypticity can be worth it if you want to create the Array with a single expression.
Less cryptic would be to create the Array with the unconditional elements first and to then conditionally insert elements, via slice(). But that leads to error-prone code, because you have to manage indices properly (insert the last one of multiple elements first, etc.).
An elegant and self-descriptive solution is to use push() to construct the Array:
const arr = [];
if (cond) {
arr.push('a');
}
arr.push('b');
A variation of the original approach is to use spread and a helper function:
const arr = [
...insertIf(cond, 'a'),
'b',
];
function insertIf(condition, ...elements) { // (A)
return condition ? elements : [];
}
In line A, the triple dots are the rest operator which collects the remaining arguments in an Array and assigns it to elements.
Another alternative is to conditionally insert either elements or undefineds and to then filter the latter values out:
const arr = [
(cond ? 'a' : undefined),
'b',
].filter(x => x !== undefined);
...)” in “Exploring ES6”