If you Wannabe (assigned) in my JS Object: Conditionally adding properties to JS Objects
Tags: javascript, beginners, webdev
Published: 2019-05-21 19:35:22

If you've worked with objects in JavaScript, you may have come across situations where you need to optionally add values to an existing object. To illustrate my example, I'd like to welcome the Spice Girls to this corner of the internet.

Traditionally, you could assign values like this:

```javascript
  function relationship(name, youGotWithMyFriends) {
    var interestedParty = {
      name: name
    }

    if(youGotWithMyFriends) {
      interestedParty.lover = true
    }

    return interestedParty
  }

  // Later in our code...
  var person = relationship('person', false)
  console.log(person) // { name: 'person'}
  var nextPerson = relationship('match', true)
  console.log(nextPerson) // { name: 'match', lover: true }
```

As the Spice Girls clearly outlined for us in 'Wannabe', you'll need to get with their friends to be a lover.

Now, one could argue that you can add the `lover` property to all the objects and have it be false by default. Totally valid, but for the purposes of this example, let's say that we don't want a `lover` property unless it is true, and keep going down this path.

What if we had to add further properties with additional guard clauses that prevent assigning falsey values to our object? it might get a little unfun to have to write `if` statements over and over.

## Modernizing our approach, with ES6

With ES6, we gained access to the spread syntax. Useful for taking values from one collection and spreading them into another one, but our above example can also leverage this syntax!

Let's have another chat with the Spice Girls and see what they think about our fun new ES6 functionality...


```javascript
  function relationship(name, youGotWithMyFriends) {
    return {
      name,
      ...(youGotWithMyFriends && { lover: true }) // !!!
    }
  }

  // Later in our code...
  const person = relationship('person', false)
  console.log(person) // { name: 'person'}
  const nextPerson = relationship('match', true)
  console.log(nextPerson) // { name: 'match', lover: true }
```

We get the same result! But umm...Spice Girls...

## What's going on?

Let's go over our line that leverages the spread operator to add that property to the return object, `...(youGotWithMyFriends && { lover: true })`, and talk a bit about what's happening.

In the case of `youGotWithMyFriends` being `true`, you end up continuing in your code and hitting the `{ lover: true }` piece, and because the spread syntax is in use, it will spread the contents of that object to the object it is nested in, giving you the second `console.log` value!

But what happens if that boolean is `false`? Can you "spread" false on to an object without an error being thrown?

The spread syntax can be thought of as a shorthand, more straightforward `Object.assign` function call. When you utilize it, it is like calling the function as follows:

```javascript
Object.assign(targetObject, thingsToAddToTarget)
```

We can see how our first example works when we use `Object.assign`, as `thingsToAddToTarget` will just be our new object. But let's talk about the case of false being passed as the second argument:

```javascript
const targetObject = {}
Object.assign(targetObject, false) // returns {}
```

Sometime during `Object.assign`'s implementation cycle, the team working on it decided that if the second argument is not an indexed value, instead of failing loudly, it will ignore what is passed in and return your original object, unmodified! Try passing a number, a null, or even undefined in your browser console as a second argument to see for yourself :).


I hope you enjoyed this little example of leveraging a cool ES6 feature, and that you can find use-cases in your code today.