How to Conditionally Add to an Object or Array in JavaScript
Tags: javascript, learning, webdev
Published: 2020-09-09 16:51:06

---
title: How to Conditionally Add to an Object or Array in JavaScript
published: true
description: How to conditionally add properties to objects or values to array in JavaScript
tags: javascript, learning, webdev
cover_image: https://amberley.dev/static/cd9341fd939c115b79bac530679d9e49/ee604/conditional-add-code-snippet.png
canonical_url: https://amberley.dev/blog/2020-09-07-conditionally-add-to-array-or-obj/
---

In the course of my work, it's not uncommon that I need to conditionally add properties to objects, or (probably less commonly) values to arrays. Let's talk about how to do both. This is the piece of code I'll ultimately use as an example:

<!-- prettier-ignore-start -->
```js
const trueCondition = true;
const falseCondition = false;

const obj = {
  ...(trueCondition && { dogs: "woof" }),
  ...(falseCondition && { cats: "meow" }),
};

// { dogs: 'woof' }

const arr = [
  ...(trueCondition ? ["dog"] : []),
  ...(falseCondition ? ["cat"] : [])
];

// ['dog']
```
<!-- prettier-ignore-end -->

First, defining a few things.

> If you're familiar with the `&&` operator, the ternary operator, and spread syntax, skip ahead.

## The logical `&&` (AND) operator

`&&` is a logical operator. Logical operators are used to "reason" about Booleans. The `&&` operator is one of three available in JavaScript (_Not material here, but for completeness -- the two others are the [`||` (OR) operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR) and [`??` (nullish coalescing) operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator)._).

### Usage

```js
// expr1 && expr2

console.log(true && "hi");
// hi

console.log("abc" && "123");
// 123

console.log({} && "empty but valid");
// empty but valid

console.log(false && "bye");
// false
```

If the first expression (on the left side) is [truthy](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) ("considered true when encountered in a Boolean context"), return **the second expression** (on the right side).

If the first expression is [falsy](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) ("considered false when encountered in a Boolean context"), return **the first expression**.

### Short-circuit evaluation

The `&&` expression is evaluated left to right. If the first expression is falsy, the full expression is short-circuit evaluated to the falsy expression (meaning the second expression is never evaluated). This is what lets us do things like safely access nested properties on an object:

```js
const obj = {};

console.log(obj.first && obj.first.second);
// undefined

console.log(obj.first.second);
// TypeError: Cannot read property 'second' of undefined
```

## The conditional (ternary) operator

The ternary operator can be thought of as a shortcut for the `if` statement. It's made of of three parts:

- A condition followed by a question mark (`?`)
- An expression to execute if the condition is truthy, followed by a colon (`:`)
- an expression to execute if the condition is falsy

```js
// condition ? exprIfConditionTrue : exprIfConditionFalse
```

An example. The two functions below accomplish the exact same thing using different syntax. The first uses `if` logic, and the second uses a ternary

```js
/*
 * Example 1
 */

function getWelcomeMessage(isLoggedIn) {
  if (isLoggedIn) {
    return "Welcome!";
  } else {
    return "Please log in.";
  }
}

console.log(getWelcomeMessage(true));
// Welcome!

console.log(getWelcomeMessage(false));
// Please log in.

/*
 * Example 2
 */

function getWelcomeMessageTernary(isLoggedIn) {
  return isLoggedIn ? "Welcome!" : "Please log in.";
}

console.log(getWelcomeMessageTernary(true));
// Welcome!

console.log(getWelcomeMessageTernary(false));
// Please log in.
```

### The spread operator (`...`)

Spread syntax can be used to [expand an iterable (like an array expression), or expand object properties](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax).

Spreading an iterable:

```js
let myDogs = [`Riggins`, `Lyla`];
let parentsDogs = [`Ellie`, `Remi`];

const holidayDoghouse = [...myDogs, ...parentsDogs];
// [ 'Riggins', 'Lyla', 'Ellie', 'Remi' ]
```

Spreading object properties:

```js
let existingAnimals = {
  dogs: 2,
  cats: 4,
  donkeys: 2,
  horses: 2,
};

let newAnimals = {
  goats: 2,
};

const allAnimals = {
  ...existingAnimals,
  ...newAnimals,
};
// { dogs: 2, cats: 4, donkeys: 2, horses: 2, goats: 2 }
```

It can be used on iterables like an array or a string.
It expands an iterable to its individual elements

## Conditionally add a property to an object

To conditionally add a property to an object, we can make use of the `&&` operator.

```js
const trueCondition = true;
const falseCondition = false;

const obj = {
  ...(trueCondition && { dogs: "woof" }),
  ...(falseCondition && { cats: "meow" }),
};

// { dogs: 'woof' }
```

In the example above, in the first property definition on `obj`, the first expression (`trueCondition`) is true/truthy, so the second expression is returned, and then spread into the object.

In the second property definition, the first expression (`falseCondition`) is false/falsy, and so the first expression is returned (and the second expression is never evaluated, because of short-circuiting). It may seem a little confusing to spread a falsy expression, but the result is that it is ignored:

```js
const spreadFalsy = {
  ...false,
  ...null,
  ...undefined,
};

console.log(spreadFalsy);
// {}
```

You don't need parentheses in evaluating these expressions, but I prefer them, to make it clear that the spread operation applies to the result of the full expression.

<!-- prettier-ignore-start -->
```js
const trueCondition = true;
const falseCondition = false;

const withParentheses = {
  ...(trueCondition && { dogs: "woof" }),
  ...(falseCondition && { cats: "meow" }),
};

// { dogs: 'woof' }

const withoutParentheses = {
  ...trueCondition && { birds: "tweet" },
  ...falseCondition && { foxes: "???" },
};

// { birds: 'tweet' }
```
<!-- prettier-ignore-end -->

## Conditionally add a value to an array

Conditionally adding a value to an array looks a little different. Rather than using an `&&` operator, we use a ternary operator.

Unlike the object spread example, if you attempt to spread on a falsy value in an array, you'll get a TypeError:

```js
const falseCondition = false;

const arr = [...(falseCondition && ["cat"])];
// TypeError: boolean false is not iterable
```

Hence we need a ternary; Using a ternary, we can fall back to spreading an empty array. Then (assuming we've correctly provided two possible iterables) both possible returned expressions will be iterables:

<!-- prettier-ignore-start -->
```js
const trueCondition = true;
const falseCondition = false;

const arr = [
  ...(trueCondition ? ["dog"] : []),
  ...(falseCondition ? ["cat"] : [])
];

// ['dog']
```
<!-- prettier-ignore-end -->