DEV Community

Andrea Simone Costa
Andrea Simone Costa

Posted on • Edited on

The shortest way to conditional insert properties into an object literal

Hi, nice to meet you ๐Ÿ˜„!
You can find this article in my personal blog here.

Latest comments (48)

Collapse
 
dubst3pp4 profile image
Marc Hanisch • Edited

I'm a year to late at the party, but thank you very much for the good explanation. I was in search for exactly this feature and it is an elegant and modern solution!

Collapse
 
jfet97 profile image
Andrea Simone Costa

Thanks!

Collapse
 
evandrix profile image
evandrix

~semplicity~ simplicity

Collapse
 
charon92 profile image
Tom Pegler

For added fun with this, I tried a couple of things:

var state = 'tom';
var o = {
  name: 'test',
  state: state,
  ...( ( true && ( this.state = 'jamie' ) ) && false ) && { state } 

}
Collapse
 
jefflindholm profile image
Jeff Lindholm

Personally, I would do it like ...(obj && { props: foo}) so it is obvious how the operators work, people who don't immediately know that && has precedence over ...won't read the code as easily.

Collapse
 
davidsharp profile image
David Sharp

This seems much nicer than my current const obj = { ...{ condition? { prop: value }: {} }}; ๐Ÿค”

While it's not entirely clear at first glance how it works, I think the intent is clear enough for someone stumbling across it (excusing any bugs caused by gotchas)

Collapse
 
ctimmerman profile image
Cees Timmerman

I know how && works, but wtf does ... do?

Collapse
 
jfet97 profile image
Andrea Simone Costa

Google rest/spread operators ๐Ÿ˜†

Collapse
 
ctimmerman profile image
Cees Timmerman • Edited

It unpacks stuff, like * in Python, which "spread" could be a synonym for, but "rest operator"? googles Ah, as in "remaining parameters".

Collapse
 
chadkirby profile image
Chad Kirby

Mind blown!

Collapse
 
stanlindsey profile image
Stan Lindsey

Basically, it evaluates like this:
...(condition && { prop: value }),

Collapse
 
carlospaz2084 profile image
Carlos

Very helpful what Stan posted here. Parenthesis really help. Actually they are a default lint recommendation in this specific case. I think adding them to the code in the article would help a lot.

Collapse
 
jfet97 profile image
Andrea Simone Costa

But it wouldn't be the shortest anymore ;)

Thread Thread
 
carlospaz2084 profile image
Carlos

hey man! I'm trying to help you here! lol...great article!

Collapse
 
danderson profile image
Dale Anderson

It's a useful trick! There are a bunch of others at blog.bitsrc.io/6-tricks-with-resti... (not my post), including a concise way to remove properties from objects.

Collapse
 
konrud profile image
Konstantin Rouda

Interesting trick, but what if our value is 0 which can be a valid value to use? So our code:

๐ฏ๐š๐ซ ๐œ๐จ๐ข๐ง๐ฌ = ๐ŸŽ;
๐ฏ๐š๐ซ ๐จ๐›๐ฃ = {
  ๐ง๐š๐ฆ๐ž: "๐‰๐จ๐ก๐ง",
  ...๐œ๐จ๐ข๐ง๐ฌ && { ๐œ๐จ๐ข๐ง๐ฌ๐€๐ฆ๐จ๐ฎ๐ง๐ญ: ๐œ๐จ๐ข๐ง๐ฌ }
}
Enter fullscreen mode Exit fullscreen mode

won't copy anything.

Collapse
 
kaptenadhoc profile image

Just make sure to internalize what JavaScript considers truthy and you won't think this is a "gotcha" anymore.

So in your specific case you'd probably want to do something like

const coins = 0;
const obj = {
  name: "John",
  ...typeof coins === "number" && !isNaN(coins) && {coins},
};
Enter fullscreen mode Exit fullscreen mode
Collapse
 
konrud profile image
Konstantin Rouda

AFAIK, this is considered as a bad practice to use typeof to check the number, as NaN is also has type number (e.g. typeof NaN === "number"; // -> true). Moreover, typeof when used against number will return number, as a result, in lower case (i.e. not Number but number).

Thread Thread
 
kaptenadhoc profile image
Reply guy ๐Ÿคทโ€โ™‚๏ธ

Yeah the casing of number was just a typo. Adjusted it to check for NaN.

Collapse
 
tkane2000 profile image
tkane2000

you could pass coins to a method that checks for false, null, and undefined only (or something along those lines)

Collapse
 
jfet97 profile image
Andrea Simone Costa • Edited

So there is no point to use the trick in this way if 0 is a valid amount as well.

Remember that on the left you put the condition, so you may write like the following:

๐ฏ๐š๐ซ ๐œ๐จ๐ข๐ง๐ฌ = ๐ŸŽ;
๐ฏ๐š๐ซ ๐จ๐›๐ฃ = {
  ๐ง๐š๐ฆ๐ž: "๐‰๐จ๐ก๐ง",
  ...๐œ๐จ๐ข๐ง๐ฌ>=0 && { ๐œ๐จ๐ข๐ง๐ฌ๐€๐ฆ๐จ๐ฎ๐ง๐ญ: ๐œ๐จ๐ข๐ง๐ฌ }
}