Conditionally Add Properties To Arrays and Objects in JavaScript

Sometimes when working on a real world project there comes a time when you might want a property added to an object only if a certain condition is met. An example might be conditionally adding a property to a style or class object in Vue, or when using clsx in React. Another situation could be if you are sending a fetch request and you want to spread certain headers in the fetch options conditionally.

This is relatively common and implemented using logical AND &&.

Conditionally Add a Property to an Object

JavaScript
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

JavaScript
const someTruthyValue = true
const someFalsyValue = ''

const arr = [
  ...(someTruthyValue && ['a']),
  ...(someFalsyValue && ['b'])
]

console.log(arr)
// ['a']

Here is a quick side by side comparison:

JavaScript
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.

JavaScript
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

JavaScript
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

JavaScript
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.

JavaScript
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.

JavaScript
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'] : []
        ]
    })
}