Conditionally Add Properties to Arrays and Objects in Javascript
I was recently creating a UI component, which was nothing more than a slideable drawer. This drawer was a function, and when opened needed to created a context object. One of the interesting things I did is found a way to mount a view app to this modal and unmount the vue app when it was removed from the DOM, but I didn't always need a vue app. This led me to find a way to conditionally add a property to the context object in the case it existed. Here is a super simplified example of how you can conditionally add properties or values to arrays or objects.
Now to understand this you may to need to do a quick review on short circuiting.
Conditionally Add a Property to an Object
const a = true
const b = false
const obj = {
...(a && { name: 'john' }),
...(b && { name: 'david' })
}
console.log(obj)
// { name: 'john' }
// lets try this again but modify obj a bit
const obj = {
...(a && { name: 'john' }),
...(a && { name: 'david' })
}
console.log(obj)
// this logs { name: 'david' } because the objects merge
const obj = {
...(true && { name: 'david' }),
...(true && { age: 30 })
}
// this will output { name: 'david', age: 30 }
Conditionally Add a Value to an Array
const someTruthyValue = true
const someFalsyValue = ''
const arr = [
...(someTruthyValue && ['a']),
...(someFalsyValue && ['b'])
]
console.log(arr)
// ['a']
Here is a quick side by side comparison:
const someTruthyValue = true
const someFalsyValue = ''
const obj = {
...(someTruthyValue && { name: 'a' }),
...(someFalsyValue && { name: 'b' })
}
const arr = [
...(someTruthyValue && ['a']),
...(someFalsyValue && ['b'])
]
Note that you can write the above code block like this without the parenthesis but you should always strive for code readability.
const someTruthyValue = true
const someFalsyValue = ''
const obj = {
...someTruthyValue && { name: 'a' },
...someFalsyValue && { name: 'b' }
}
const arr = [
...someTruthyValue && ['a'],
...someFalsyValue && ['b']
]
Here falsy value is an empty string which can be spread, but the below code would fail because false
cannot be spread out
const someTruthyValue = true
const someFalsyValue = false
const obj = {
...someTruthyValue && { name: 'a' },
...someFalsyValue && { name: 'b' }
}
const arr = [
...someTruthyValue && ['a'],
...someFalsyValue && ['b']
]
In this case we need to make sure in the case that the array has a falsy value that cannot be spread we cover that case with the ternary operator
const someTruthyValue = true
const someFalsyValue = false
const obj = {
...someTruthyValue && { name: 'a' },
...someFalsyValue && { name: 'b' }
}
const arr = [
...someTruthyValue ? ['a'] : [],
...someFalsyValue ? ['b'] : []
]
Conditional properties can also be nested.
const showAge = true
const showId = false
const showUserDetails = true
const user = {
email: 'test@gmail.com',
...(showUserDetails && {
name: 'david',
...(showAge && { age: 29 }),
...(showId && { id: 1 })
})
}
// { name: 'david', age: 29}
/**
* here showId is true
*/
const showAge = true
const showId = true
const showUserDetails = true
const user = {
email: 'test@gmail.com',
...(showUserDetails && {
name: 'david',
...(showAge && { age: 29 }),
...(showId && { id: 1 })
})
}
// { name: 'david', age: 29, id: 1}
This last example seems a bit complicated but it is a good excercise. Pay close attention to the code and notice that it does look long and complex but it just takes the simple concepts from above and reuses them.
const x = true
const y = false
const obj = {
foo: 'foo',
bar: [
...x ? [{ id: 1 }] : [],
...y ? [{ id: 2 }] : [],
{ id: 3 }
],
...(x && {
baz: [
...x ? ['a'] : [],
'b',
...y ? ['c'] : []
]
})
}