In Javascript, how to conditionally add a member to an object?

I would like to create an object with an added member. Simple approach:

var a = {}; if (someCondition) ab = 5; 

Now I would like to write more idiomatic code. I'm trying to:

 a = { b: (someCondition? 5 : undefined) }; 

But now b is a member of a whose value is undefined . This is not the desired result.

Is there a convenient solution?

Update

I am looking for a solution that could handle a common case with multiple members.

 a = { b: (conditionB? 5 : undefined), c: (conditionC? 5 : undefined), d: (conditionD? 5 : undefined), e: (conditionE? 5 : undefined), f: (conditionF? 5 : undefined), g: (conditionG? 5 : undefined), }; 
+277
javascript
Jul 28 2018-12-12T00:
source share
16 answers

In pure Javascript, I can't come up with anything more idiomatic than your first piece of code.

If, however, using the jQuery library is out of the question, then $. extend () should meet your requirements because, as the documentation says:

Undefined properties are not copied.

Therefore, you can write:

 var a = $.extend({}, { b: conditionB ? 5 : undefined, c: conditionC ? 5 : undefined, // and so on... }); 

And get the expected results (if conditionB is false , then b will not exist in a ).

+93
Jul 28 '12 at 20:45
source share

I think @InspiredJW did this with ES5, and as @trincot pointed out, using es6 is the best approach. But we can add a little more sugar using the spread operator, and a logical AND short circuit:

 const a = { ...(someCondition && {b: 5}) } 
+623
Nov 12 '16 at 8:22
source share

With EcmaScript2015 you can use Object.assign :

 Object.assign(a, conditionB ? { b: 1 } : null, conditionC ? { c: 2 } : null, conditionD ? { d: 3 } : null); 

 var a, conditionB, conditionC, conditionD; conditionC = true; a = {}; Object.assign(a, conditionB ? { b: 1 } : null, conditionC ? { c: 2 } : null, conditionD ? { d: 3 } : null); console.log(a); 

Some notes:

Even more concise

Taking the second paragraph further, you can shorten it as follows (as @Jamie noted), since false values ​​do not have their own enumerated properties ( false , 0 , NaN , null , undefined , '' , except document.all ):

 Object.assign(a, conditionB && { b: 1 }, conditionC && { c: 2 }, conditionD && { d: 3 }); 

 var a, conditionB, conditionC, conditionD; conditionC = "this is truthy"; conditionD = NaN; // falsy a = {}; Object.assign(a, conditionB && { b: 1 }, conditionC && { c: 2 }, conditionD && { d: 3 }); console.log(a); 
+81
Jul 20 '16 at 14:10
source share

Using extended syntax with a boolean value (as suggested here) is not a valid syntax. Propagation can only be used with iterations .

I suggest the following:

 const a = { ...(someCondition? {b: 5}: {} ) } 
+33
Mar 28 '19 at 11:24
source share
 const obj = { ...(condition) && {someprop: propvalue}, ...otherprops } 
+26
Jul 05 '18 at 22:00
source share

How about using the extended properties of an object and only set the property if it is true, for example:

 [isConditionTrue() && 'propertyName']: 'propertyValue' 

Therefore, if the condition is not met, it does not create a preferred property and, therefore, you can cancel it. See: http://es6-features.org/#ComputedPropertyNames

UPDATE: It's even better to follow Axel Rauschmeier's approach in his blog article on conditionally adding entries inside object literals and arrays ( http://2ality.com/2017/04/conditional-literal-entries.html ):

 const arr = [ ...(isConditionTrue() ? [{ key: 'value' }] : []) ]; const obj = { ...(isConditionTrue() ? {key: 'value'} : {}) }; 

They helped me a lot.

+24
Nov 16 '17 at 13:48 on
source share

If the goal is for the object to be self-contained and within the same set of curly braces, you can try the following:

 var a = new function () { if (conditionB) this.b = 5; if (conditionC) this.c = 5; if (conditionD) this.d = 5; }; 
+5
Jul 28 '12 at 20:57
source share

If you want to make this server side (without jquery) you can use lodash 4.3.0:

 a = _.pickBy({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined)); 



And this works using lodash 3.10.1

 a = _.pick({ b: (someCondition? 5 : undefined) }, _.negate(_.isUndefined)); 
+5
Feb 11 '16 at 1:29
source share

This has long been answered, but looking at other ideas, I came up with an interesting derivative:

Assign undefined values ​​to the same property and then delete it

Create your object using an anonymous constructor and always assign undefined members the same dummy element that you delete at the very end. This will give you one line (not too complicated, hopefully) per member + 1 extra line at the end.

 var a = new function() { this.AlwaysPresent = 1; this[conditionA ? "a" : "undef"] = valueA; this[conditionB ? "b" : "undef"] = valueB; this[conditionC ? "c" : "undef"] = valueC; this[conditionD ? "d" : "undef"] = valueD; ... delete this.undef; }; 
+4
Dec 10 '14 at 1:54
source share
 var a = { ...(condition ? {b: 1} : '') // if condition is true 'b' will be added. } 

Hopefully this is a very effective way to add a condition based entry. Learn more about how to conditionally add entries inside object literals.

+4
Dec 29 '17 at 10:19 on
source share

I would do it

 var a = someCondition ? { b: 5 } : {}; 

Edited with one version of string code

+1
Jul 28 '12 at 20:10
source share

I think your first approach to adding members is conditional - that’s fine. I do not agree that I do not want to have a b of a member with an undefined value. It is simple enough to add an undefined check using a for loop with an in statement. But in any case, you can easily write a function to filter undefined members.

 var filterUndefined = function(obj) { var ret = {}; for (var key in obj) { var value = obj[key]; if (obj.hasOwnProperty(key) && value !== undefined) { ret[key] = value; } } return ret; }; var a = filterUndefined({ b: (conditionB? 5 : undefined), c: (conditionC? 5 : undefined), d: (conditionD? 5 : undefined), e: (conditionE? 5 : undefined), f: (conditionF? 5 : undefined), g: (conditionG? 5 : undefined), }); 

You can also use the delete operator to edit the object in place.

0
Jul 28 '12 at 20:50
source share

Using the lodash library, you can use _.omitBy

 var a = _.omitBy({ b: conditionB ? 4 : undefined, c: conditionC ? 5 : undefined, }, _.IsUndefined) 

This is useful if you have queries that are optional.

 var a = _.omitBy({ b: req.body.optionalA, //if undefined, will be removed c: req.body.optionalB, }, _.IsUndefined) 
0
May 18 '18 at 10:59
source share

You can add all your undefined values ​​without any conditions, and then use JSON.stringify to remove all of them:

 const person = { name:undefined, age:22, height:null } const cleaned = JSON.parse(JSON.stringify(person)); //cleaned = { // age:22, // height:null // } 
0
Jul 15 '18 at 9:06
source share

Wrap in object

Something like this is a little cleaner

  const obj = { X: 'dataX', Y: 'dataY', //... } const list = { A: true && 'dataA', B: false && 'dataB', C: 'A' != 'B' && 'dataC', D: 2000 < 100 && 'dataD', // E: conditionE && 'dataE', // F: conditionF && 'dataF', //... } Object.keys(list).map(prop => list[prop] ? obj[prop] = list[prop] : null) 

Wrap in an array

Or, if you want to use the Jamie Hill method and have a very long list of conditions, you have to write ... syntax several times. To make it a little cleaner, you can simply wrap them in an array and then use reduce() to return them as a single object.

 const obj = { X: 'dataX', Y: 'dataY', //... ...[ true && { A: 'dataA'}, false && { B: 'dataB'}, 'A' != 'B' && { C: 'dataC'}, 2000 < 100 && { D: 'dataD'}, // conditionE && { E: 'dataE'}, // conditionF && { F: 'dataF'}, //... ].reduce(( v1, v2 ) => ({ ...v1, ...v2 })) } 

Or using the map() function

 const obj = { X: 'dataX', Y: 'dataY', //... } const array = [ true && { A: 'dataA'}, false && { B: 'dataB'}, 'A' != 'B' && { C: 'dataC'}, 2000 < 100 && { D: 'dataD'}, // conditionE && { E: 'dataE'}, // conditionF && { F: 'dataF'}, //... ].map(val => Object.assign(obj, val)) 
0
May 6 '19 at 12:38
source share

Using the lodash library you can use _.merge

 var a = _.merge({}, { b: conditionB ? 4 : undefined, c: conditionC ? 5 : undefined, }) 
  1. If the condition is false and the condition a = { c: 5 } true , then a = { c: 5 }
  2. If both conditions a = { b: 4, c: 5 } & conditionC true , then a = { b: 4, c: 5 }
  3. If both conditions B & conditionC false , then a = {}
-one
Mar 26 '18 at 19:15
source share



All Articles