a--m
a--m

Reputation: 4782

ES6 property value shorthand of undefined

I would like to use property value shorthand but only when the value is defined, consider the following example:

const personByName = name => {
  const person = http(name)
  return { person, method: 'byName' }
}

personByName('john') // found person: { person: { name: 'john', age: 30 }, method: 'byName' }
personByName('paul') // not found: { method: 'byName' }

But the current output I get is:

personByName('paul') // not found: { person: undefined, method: 'byName' }

Upvotes: 2

Views: 1763

Answers (4)

Exodus 4D
Exodus 4D

Reputation: 2822

In ES2018 this can be done even without "type checks"

let a = { a: 1 }
let b = { b: 2 }
let c = undefined
let d = { d: 4 }

let x = {...a, ...b, ...c, ...d};      // {a: 1, b: 2, d: 4}
//                      ┗━━ undefined
console.log(x)

This works for falsy vars. Some attention to "non empty strings":

let a = { a: 1 }
let b = { b: 2 }
let c = undefined // ━┓
let c1 = false    //  ╏
let c2 = 0        //  ╏
let c3 = -0       //  ┣╍ falsy
let c4 = 0n       //  ╏
let c5 = ''       //  ╏
let c6 = null     //  ╏
let c7 = NaN      // ━┛
let d = { d: 4 }

let x = {...a, ...b, ...c, ...c1, ...c2, ...c3, ...c4, ...c5, ...c6, ...c7, ...d}; 
//                      ┗━━━━━━━━━━━━━━━━━━━━ falsy ━━━━━━━━━━━━━━━━━━━━━┛
console.log(x)   // OK: {a: 1, b: 2, d: 4}

let t1 = true   
let t2 = 789
let y = {...a, ...b, ...t1, ...t2, ...d}; 
console.log(y)   // OK: {a: 1, b: 2, d: 4}

// Non empty string!
let t3 = 'abc'
let z = {...a, ...b, ...t3, ...d}; 
console.log(z)   // {0: "a", 1: "b", 2: "c", a: 1, b: 2, d: 4}
//                   ┗━━━━━━━ !!! ━━━━━━━┛

Upvotes: 0

Daniel A. White
Daniel A. White

Reputation: 190945

I think you want something like this:

const personByName = name => {
  const person = http(name);
  const result = { method: 'byName' };
  if (person) { result.person = person; }
  return result;
}

There's no skipping declaring a property on an object if it's undefined.

Upvotes: 1

Matías Fidemraizer
Matías Fidemraizer

Reputation: 64923

In ES2018, you may use the ternary operator to eval if a defined and object spread to build an object which contains a and b, or just b:

const a = 1
const b = { b: 2 }
const c = a ? { a, ...b } : b

console.log( c ) 

const a = undefined
const b = { b: 2 }
const c = a ? { a, ...b } : b

console.log( c ) 

Upvotes: 1

Estus Flask
Estus Flask

Reputation: 222493

In order to use shorthand property, Object.assign can be used:

const personByName = name => {
  const person = http(name);
  return Object.assign({ method: 'byName' }, person && { person });
}

Subsequent non-object Object.assign arguments are efficiently ignored, so falsy person doesn't affect the result.

This will work if person is expected to be an object, like is shown in original code.

In case only undefined values aren't allowed, it's:

Object.assign({ method: 'byName' }, person !== undefined && { person });

Upvotes: 4

Related Questions