DEV Community

Cover image for How to conditionally build an object in ES6
Knut Melvær for Sanity.io

Posted on • Originally published at sanity.io

How to conditionally build an object in ES6

I've been tinkering with RSS-feeds for podcasts in CLIs, Express and Serverless functions lately, which involves both parsing and constructing complex objects with lots of fields and information. Since you're dealing with user-generated data from different sources, you aren't guaranteed that all fields are populated all the times. Some fields are optional as well.

Earlier I would deal with this by conditionally applying new keys on an object like this:

function episodeParser(data) {
  const { id, 
    title,
    description,
    optionalField,
    anotherOptionalField
  } = data
  const parsedEpisode = { guid: id, title, summary: description }
  if (optionalField) {
    parsedEpisode.optionalField = optionalField
  } else if (anotherOptionalField) {
    parsedEpisode.anotherOptionalField = anotherOptionalField
  }
  // and so on
  return parsedEpisode
}
Enter fullscreen mode Exit fullscreen mode

This isn't exactly smooth (but it works). I could also do nifty things with looping the object keys and so on, but that entails code that's a bit more convoluted and you don't get a good sense of what the data object is either.

Yet again, new syntax in ES6 comes to the rescue, and I found a pattern where I was able to rewrite the code over to something like this:

function episodeParser({
    id, 
    title, 
    description = 'No summary', 
    optionalField, 
    anotherOptionalField
}) {
    return {
      guid: id,
      title,
      summary: description,
      ...(optionalField && {optionalField},
      ...(anotherOptionalField && {anotherOptionalField})
    }
}
Enter fullscreen mode Exit fullscreen mode

If we put the function into action, it would look something like this:

const data = { 
  id: 1, 
  title: 'An episode', 
  description: 'An episode summary', 
  anotherOptionalField: 'some data' 
}
episodeParser(data)
//> { guid: 1, title: 'An episode', summary: 'An episode summary', anotherOptionalField: 'some data' }
Enter fullscreen mode Exit fullscreen mode

This function has a couple of features. The first is parameter object destructuring, which is a good pattern if you want to deal with lots of arguments in a function. The second is the three dots spread syntax (...), which here is used to “spread” the object if the condition is true-ish, which we check if the AND operator (&&). What you end up with is a neat concise function which is also easy to test.

You can see it action in our podcast feeds implementation for express.js and netlify lambdas.

Top comments (3)

Collapse
 
kepta profile image
Kushan Joshi • Edited

One of the great pitfalls of using ‘&& ||’ is that you rely on falsy values. It becomes painful when you are dealing with numbers and you have a habbit of simply using the shorthand and “0” gets treated as falsy. For example if I modify your code slightly:

function episodeParser({
    id, 
    title, 
    description = 'No summary', 
    optionalField, 
    anotherOptionalField
}) {
    return {
      ...(id && {guid: id})
      title,
      summary: description,
      ...(optionalField && {optionalField},
      ...(anotherOptionalField && {anotherOptionalField})
    }
}

let p = episodeParser({id: 0})
p.guid // undefined ! wtf?
Collapse
 
kmelve profile image
Knut Melvær

Ah, the many pitfalls of JavaScript 😅 In this case it id is always a string, but it's good that you point that gotcha out! 👌

Collapse
 
zachkshaw profile image
Zach Shaw

Love this! Nice!