skip to Main Content

Is there any approach in JS to initialize a property of an object conditionally? I can’t find any information about this yet.

Example: there is a variable, and if it is not null or undefined, then when initializing the object you are able to add a property with its value in one line.

let optionA = "Some option";

const obj = {
   id: 1,
   name: "Object 1",
   ?optionA, // if 'optionA' then add property
}

I know only one way: add optional properties after initialization only.

const obj = {
   id: 1,
   name: "Object 1",
}

if (optionA) {
   obj.optionA = optionA;
}
if (optionB) {
   obj.optionA = optionB;
}
if (optionC) {
   obj.optionA = optionC;
}
if (optionD) {
   obj.optionA = optionD;
}

As you may have noticed, in this case it is not possible to use a one-line object property shorthand for convenience or a ternary operator, the code becomes bloated.

All I could find is adding a property with the spread operator but this looks even worse than if statement.


I also noticed that this principle is partially implemented in the fetch API:

let optionA;

const req = await fetch('https://jsonplaceholder.typicode.com/posts', {
  method: 'POST',
  body: JSON.stringify({
    title: 'foo',
    body: 'bar',
    userId: 1,
    optionA,
  }),
  headers: {
    'Content-type': 'application/json; charset=UTF-8',
  },
})
  .then((response) => response.json())
  .then((json) => console.log(json));

// {title: 'foo', body: 'bar', userId: 1, id: 101}

It works with undefined only and will log the response without optionA property because it will be removed from the body in the request payload.

4

Answers


  1. You could use a getter to set a property to specific value when initializing an object. However this will always create the property even if null.

    IMO this should not matter much as you can check on the prop instead to check if the prop exists.

    Maybe I’m missing a reason why.

    // TEST CASE 1
    
    let optionA = 'a'
    
    const obj = {
       id: 1,
       name: "Object 1",
       get optionA() {
       return optionA ?? optionB ?? optionC ?? optionD ?? null
       }
    }
    
    console.log(obj)
    
    // TEST CASE 2
    
    optionA = null
    let optionB = 'b'
    
    const obj2 = {
       id: 1,
       name: "Object 2",
       get optionA() {
       return optionA ?? optionB ?? optionC ?? optionD ?? null
       }
    }
    
    console.log(obj2)
    
    // TEST CASE 3
    
    optionA = null
    optionB = null
    optionC = null
    optionD = null
    
    
    const obj3 = {
       id: 1,
       name: "Object 3",
       get optionA() {
       return optionA ?? optionB ?? optionC ?? optionD ?? null
       }
    }
    
    console.log(obj3)
    Login or Signup to reply.
  2. You could spread a new object or an empty one, depending on the value (== with null/undefined).

    const
        a = 0,
        b = 1,
        x = undefined,
        y = null;
    
    console.log({
        ...a == null ? {} : { a },
        ...b == null ? {} : { b },
        ...x == null ? {} : { x },
        ...y == null ? {} : { y }
    });
    Login or Signup to reply.
  3. Use the object shortcut plus Object.entries() plus Array::forEach() to get an one-liner:

    const obj = {
       id: 1,
       name: "Object 1",
    }
    
    const optionA = null, optionB = 'optionB', optionC = false;
    let optionD;
    
    Object.entries({optionA, optionB, optionC, optionD}).forEach(([k, v]) => v && (obj.optionA = v));
    
    console.log(obj);
    Login or Signup to reply.
  4. You can wrap the logic from the link in a function and use that. To me this looks pretty readable and also shows the intent clearly.

    function ifHasValue(option) {
       return option ? { [option]: option } : undefined;
    }
    

    Demo:

    function ifHasValue(option) {
      return option ? { [option]: option } : undefined;
    }
    
    let optionA = "";
    let optionB = "Some option";
    let optionC = undefined;
    let optionD = null;
    
    const obj = {
      id: 1,
      name: "Object 1",
      ...ifHasValue(optionA),
      ...ifHasValue(optionB),
      ...ifHasValue(optionC),
      ...ifHasValue(optionD)
    };
    
    console.log(obj);
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search