Search code examples
javascriptobjectlogical-operatorsshortcut

Looking for shorthand to insert a variable into object if not null


Often I have several named variable, and I want to put them into an object if they are not null or undefined. JavaScript has several nice shortcuts for building objects, so I figure there must be one for this use case.

I usually do something like this. But it is so verbose.

function foo(a, b) {
  return {...(isNotNullish(a) ? {a} : {}), ...(isNotNullish(b) ? {b} : {})};
}
// the result I want is:
// foo(6, 7) == {a: 6, b: 7}
// foo(6) == {a: 6}
// foo() == {}

Is there a better way?


Solution

  • I'm afraid there's no real shorter way of doing this (well technically a minor one and then somewhat more obtuse one)

    I tried playing around with the nullish operator ??, but I have to say the working solution seems uglier than what I'm a bout to propose.

    Essentially it boils down to the fact, you're looking for the negation of the nullish operator (or alternatively a nullish ternary), neither of which sadly exist (yet).

    Here's a relatively compact solution, which just improves upon your solution and simplifies it with the usage of the && logical AND operator

    const notNullish = (value) =>
      value !== null && typeof value !== 'undefined'
    
    const foo = (a, b) => ({
      ...(notNullish(a) && {a}),
      ...(notNullish(b) && {b}),
     })
    
    console.log('foo(6, 7) =>', foo(6, 2))
    console.log('foo(6) =>', foo(6))
    console.log('foo() =>', foo())
    console.log('foo(0, false) =>', foo(0, false))

    Now as I said, there's no optimal way of doing this, because while the you can use the logical ?? to check, it cannot directly assign to object property at the same time. Best I could come up with is:

    const notNullish = (key, value) => {
       const nullishCheck = value ?? 'IS_NULLISH'
       return nullishCheck === 'IS_NULLISH'
          ? {}
          : {[key]: value}
    }
    
    const foo = (a, b) => ({
       ...notNullish('a', a),
       ...notNullish('b', b)
    })
    
    console.log(foo(6, 4))
    console.log(foo(6))
    console.log(foo())
    console.log(foo(0, false))

    But personally I find the second snippet kinda ugly and would probably just go with the first option, especially for the following three reasons

    1. In my opinion it just looks plain uglier
    2. The ?? operator is not yet fully supported on Explorer and Node.js
    3. Chances are not a lot of people are even familiar with the operator and it forces you to not even use it directly, but rather as an assignment check.