A way to prevent properties to be added to an object if they are null or undefined.

# Rodrigo Carranza (9 months ago)

A way to prevent properties to be added to an object if they are null or undefined.

Currently this can be accomplished in many ways:

With an if:

function foo(couldBeNull){
let ret = {}
if(couldBeNull){
ret.couldBeNull = couldBeNull
}
return  ret
}

With ternary (kind of gross)

function foo(couldBeNull){
let ret = {}
couldBeNull ? (ret.couldBeNull = couldBeNull) : null
return  ret
}

Also gross

function foo(couldBeNull){
let ret = {}
couldBeNull && (ret.couldBeNull = couldBeNull)
return  ret
}

A bit hard to read:

function foo(couldBeNull){
let ret = {
...({couldBeNull} : {})
}
return  ret
}

Requires importing a lib or writing the function by yourself. Also it has to iterate over all values

function foo(couldBeNull){
let ret = {
couldBeNull
}
ret = removeEmptyValues(ret) // imported from some library
return  ret
}

Wouldn't it be better something like this?:

function foo(couldBeNull){
let ret = {
couldBeNull?
}
return  ret
}

Or if you want to set other property name

function foo(couldBeNull){
let ret = {
bar ?:  couldBeNull // bar is not added if couldBeNull is null or undefined
}
return  ret
}

[ipmcdn.avast.com/images/icons/icon-envelope-tick-round-orange-animated-no-repeat-v1.gif]www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient Libre de virus. www.avast.comwww.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient

# Sebastian Malton (9 months ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20171128/750cba12/attachment-0001

# Rodrigo Carranza (9 months ago)

It's about the value of the property to be added, nothing to do with the name of the property. It should discard properties whose value are null(but this behavior is not always desired, so a different syntax for these properties should be added).


On nov. 28 2017, at 8:33 pm, Sebastian Malton <sebastian at malton.name> wrote:

I am sort of confused about what you are asking, is the check about the property name or the current value of the property?


Sebastian Malton

From: rodrigocarranza at outlook.com
Sent: November 28, 2017 8:30 PM
To: es-discuss at mozilla.org
Subject: A way to prevent properties to be added to an object if they are null or undefined.


A way to prevent properties to be added to an object if they are null or undefined.

Currently this can be accomplished in many ways:

With an if:
```js
function foo(couldBeNull){
let ret = {}
if(couldBeNull){
ret.couldBeNull<http://ret.couldBeNull> = couldBeNull
}
return  ret
}

With ternary (kind of gross)

function foo(couldBeNull){
let ret = {}
couldBeNull ? (ret.couldBeNull<http://ret.couldBeNull> = couldBeNull) : null

return  ret
}

Also gross

function foo(couldBeNull){
let ret = {}
couldBeNull && (ret.couldBeNull<http://ret.couldBeNull> = couldBeNull)

return  ret
}

A bit hard to read:

function foo(couldBeNull){
let ret = {
...({couldBeNull} : {})
}
return  ret
}

Requires importing a lib or writing the function by yourself. Also it has to iterate over all values

function foo(couldBeNull){
let ret = {
couldBeNull
}
ret = removeEmptyValues(ret) // imported from some library
return  ret
}

Wouldn't it be better something like this?:

function foo(couldBeNull){
let ret = {
couldBeNull?
}
return  ret
}

Or if you want to set other property name

function foo(couldBeNull){
let ret = {
bar ?:  couldBeNull // bar is not added if couldBeNull is null or undefined
}
return  ret
}

[ipmcdn.avast.com/images/icons/icon-envelope-tick-round-orange-animated-no-repeat-v1.gif]www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient Libre de virus. www.avast.comwww.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=emailclient

# Sebastian Malton (9 months ago)

An HTML attachment was scrubbed... URL: esdiscuss/attachments/20171128/228d2cd2/attachment-0001

# Michał Wadas (9 months ago)

You can just use proxy with proper set trap.

# J Decker (9 months ago)

Or feed it through JSON.parse( JSON.strinigfy( o ) ) which will delete undefined things; doesn't help with null.

# Bob Myers (9 months ago)

The usual idiom is

Object.assign({}, couldBeNull && {couldBeNull})

taking advantage of the fact that Object.assign skips over non-object parameters.

I don't understand your proposed

let ret = {...({couldBeNull} : {})}

and it seems to be syntactically wrong, but if you want to use object spread syntax you could write

{...couldBeNull && {couldBeNull}}
# Rodrigo Carranza (9 months ago)

Yes, like that, but that will require to modify the object.

Compare this

let a = {}
a.field ?= couldBeNull

To:

let a = {
  field ?: couldBeNull
}

Also if you want to set the property with the same name of the variable

let field = ...
let a = {
  field?
}

Why this is useful? Well, is not the biggest change but it could make the language more expressive. Also this is similar to how Typescript declares optional properties in object interfaces.

interface User{
  id: string,
  username: string,
  age?: number,
}

then:

function createUser({id, username, age}){
  db.user.insertOne({id, username, age?})
}



On nov. 28 2017, at 8:45 pm, Sebastian Malton <sebastian at malton.name> wrote:

So something like the following?


```js
a.field ?= value;

And this sets the property field of object a to value if value != null.

Sebastian Malton

From: rodrigocarranza at outlook.com Sent: November 28, 2017 8:40 PM To: sebastian at malton.name Cc: es-discuss at mozilla.org Subject: Re: A way to prevent properties to be added to an object if they are null or undefined.

It's about the value of the property to be added, nothing to do with the name of the property. It should discard properties whose value are null(but this behavior is not always desired, so a different syntax for these properties should be added).


On nov. 28 2017, at 8:33 pm, Sebastian Malton <sebastian at malton.name<mailto:sebastian at malton.name>> wrote:

I am sort of confused about what you are asking, is the check about the property name or the current value of the property?


Sebastian Malton

From: rodrigocarranza at outlook.com<mailto:rodrigocarranza at outlook.com>

Sent: November 28, 2017 8:30 PM
To: es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>

Subject: A way to prevent properties to be added to an object if they are null or undefined.


A way to prevent properties to be added to an object if they are null or undefined.

Currently this can be accomplished in many ways:

With an if:
```js
function foo(couldBeNull){
let ret = {}
if(couldBeNull){
ret.couldBeNull<http://ret.couldbenull/?recipient=es-discuss%40mozilla.org> = couldBeNull
}
return  ret
}

With ternary (kind of gross)

function foo(couldBeNull){
let ret = {}
couldBeNull ? (ret.couldBeNull<http://ret.couldbenull/?recipient=es-discuss%40mozilla.org> = couldBeNull) : null

return  ret
}

Also gross

function foo(couldBeNull){
let ret = {}
couldBeNull && (ret.couldBeNull<http://ret.couldbenull/?recipient=es-discuss%40mozilla.org> = couldBeNull)

return  ret
}

A bit hard to read:

function foo(couldBeNull){
let ret = {
...({couldBeNull} : {})
}
return  ret
}

Requires importing a lib or writing the function by yourself. Also it has to iterate over all values

function foo(couldBeNull){
let ret = {
couldBeNull
}
ret = removeEmptyValues(ret) // imported from some library
return  ret
}

Wouldn't it be better something like this?:

function foo(couldBeNull){
let ret = {
couldBeNull?
}
return  ret
}

Or if you want to set other property name

function foo(couldBeNull){
let ret = {
bar ?:  couldBeNull // bar is not added if couldBeNull is null or undefined
}
return  ret
}

[ipmcdn.avast.com/images/icons/icon-envelope-tick-round-orange-animated-no-repeat-v1.gif]www.avast.com/sig-email?utm_medium=email&%3Butm_source=link&%3Butm_campaign=sig-email&%3Butm_content=emailclient&recipient=es-discuss%40mozilla.org Libre de virus. www.avast.comwww.avast.com/sig-email?utm_medium=email&%3Butm_source=link&%3Butm_campaign=sig-email&%3Butm_content=emailclient&recipient=es-discuss%40mozilla.org

# Rodrigo Carranza (9 months ago)

Yes, like that, but that will require to modify the object.

Compare this

let a = {}
a.field ?= couldBeNull

To:

let a = {
  field ?: couldBeNull
}

Also if you want to set the property with the same name of the variable

let field = ...
let a = {
  field?
}

Why this is useful? Well, is not the biggest change but it could make the language more expressive. Also this is similar to how Typescript declares optional properties in object interfaces.

interface User{
  id: string,
  username: string,
  age?: number,
}

then:

function createUser({id, username, age}){
  db.user.insertOne({id, username, age?})
}



On nov. 28 2017, at 8:45 pm, Sebastian Malton <sebastian at malton.name> wrote:

So something like the following?


```js
a.field ?= value;

And this sets the property field of object a to value if value != null.

Sebastian Malton

From: rodrigocarranza at outlook.com Sent: November 28, 2017 8:40 PM To: sebastian at malton.name Cc: es-discuss at mozilla.org Subject: Re: A way to prevent properties to be added to an object if they are null or undefined.

It's about the value of the property to be added, nothing to do with the name of the property. It should discard properties whose value are null(but this behavior is not always desired, so a different syntax for these properties should be added).


On nov. 28 2017, at 8:33 pm, Sebastian Malton <sebastian at malton.name<mailto:sebastian at malton.name>> wrote:

I am sort of confused about what you are asking, is the check about the property name or the current value of the property?


Sebastian Malton

From: rodrigocarranza at outlook.com<mailto:rodrigocarranza at outlook.com>

Sent: November 28, 2017 8:30 PM
To: es-discuss at mozilla.org<mailto:es-discuss at mozilla.org>

Subject: A way to prevent properties to be added to an object if they are null or undefined.


A way to prevent properties to be added to an object if they are null or undefined.

Currently this can be accomplished in many ways:

With an if:
```js
function foo(couldBeNull){
let ret = {}
if(couldBeNull){
ret.couldBeNull<http://ret.couldbenull/?recipient=sebastian%40malton.name> = couldBeNull
}
return  ret
}

With ternary (kind of gross)

function foo(couldBeNull){
let ret = {}
couldBeNull ? (ret.couldBeNull<http://ret.couldbenull/?recipient=sebastian%40malton.name> = couldBeNull) : null

return  ret
}

Also gross

function foo(couldBeNull){
let ret = {}
couldBeNull && (ret.couldBeNull<http://ret.couldbenull/?recipient=sebastian%40malton.name> = couldBeNull)

return  ret
}

A bit hard to read:

function foo(couldBeNull){
let ret = {
...({couldBeNull} : {})
}
return  ret
}

Requires importing a lib or writing the function by yourself. Also it has to iterate over all values

function foo(couldBeNull){
let ret = {
couldBeNull
}
ret = removeEmptyValues(ret) // imported from some library
return  ret
}

Wouldn't it be better something like this?:

function foo(couldBeNull){
let ret = {
couldBeNull?
}
return  ret
}

Or if you want to set other property name

function foo(couldBeNull){
let ret = {
bar ?:  couldBeNull // bar is not added if couldBeNull is null or undefined
}
return  ret
}

[ipmcdn.avast.com/images/icons/icon-envelope-tick-round-orange-animated-no-repeat-v1.gif]www.avast.com/sig-email?utm_medium=email&%3Butm_source=link&%3Butm_campaign=sig-email&%3Butm_content=emailclient&recipient=sebastian%40malton.name Libre de virus. www.avast.comwww.avast.com/sig-email?utm_medium=email&%3Butm_source=link&%3Butm_campaign=sig-email&%3Butm_content=emailclient&recipient=sebastian%40malton.name

# Rodrigo Carranza (9 months ago)

Yeah, it was wrong, I'm currently using like

let ret = { ... ( couldBeNull ? {couldBeNull} : {} ) }

Yours is better and the usual idiom a bit hard to understand.

What I'm proposing is something like this

let ret = { couldBeNull? }

or if you want a different name for the property

let ret = { bar ?: couldBeNull }

It is not like there is no way to do this, there are plenty. But this way could make code a bit easier to read.

P.D: Sorry for the duplicates and that new thread, I don't understand so much this client and it is acting weird. Also I'm new to mailing lists.

# kai zhu (9 months ago)

@rodrigo, you can achieve most of what you want with a simple helper function. my suspicion is there are too many variations for this to be practical as a language proposal (e.g. you often want the empty string "" to be considered nullish as well for the special nodejs object process.env, which silently converts all set items to string).

/*jslint node: true*/
'use strict';
var obj, objectSetNonNullishProperty, propertyDict;



objectSetNonNullishProperty = function (obj, propertyDict) {
/*
 * this function will assign all non-nullish items in propertyDict to obj
 * edit it to suit your needs and variations
 */
    var value;
    Object.keys(propertyDict).forEach(function (key) {
        value = propertyDict[key];
        if (value !== null && value !== undefined) {
            obj[key] = value;
        }
    });
    return obj;
};



// test assigning non-nullish properties to empty obj
obj = {};
propertyDict = {
    aa: null,
    bb: undefined,
    cc: 0,
    dd: false,
    ee: ''
};
console.assert(JSON.stringify(
    objectSetNonNullishProperty(obj, propertyDict)
) === JSON.stringify({
    cc: 0,
    dd: false,
    ee: ''
}));



// test overriding obj with non-nullish properties
obj = {
    aa: 1,
    bb: 2,
    cc: 3,
    dd: 4,
    ee: 5
};
propertyDict = {
    aa: null,
    bb: undefined,
    cc: 0,
    dd: false,
    ee: ''
};
console.assert(JSON.stringify(
    objectSetNonNullishProperty(obj, propertyDict)
) === JSON.stringify({
    aa: 1,
    bb: 2,
    cc: 0,
    dd: false,
    ee: ''
}));
# Jerry Schulteis (9 months ago)

I was about to hit send on a post also suggesting a helper function, but after thinking about it a bit more, Rodrigo's suggestion resembles extending the optional chaining proposal tc39/proposal-optional-chaining into the object literal notation. I suggest using the same character pair, "?.", as is proposed for optional chaining, instead of just "?".

let ret = {
    couldBeNull?.,
    bar?.: couldBeNull
}

The helper function might be best in the case where an empty string value needs the same treatment as null or undefined.

# Rodrigo Carranza (9 months ago)

I know how to do it, also, what about nested objects. It is not about serialization, and falsy values should be explicitly compared to their own empty value.

const propertyDict = {
  aa ?: null,
  bb ?: undefined,
  cc ?:  couldBeZero !== 0 ? couldBeZero : null,
  dd ?: couldBeFalse !== False ? couldBeFalse : null,
  ee ?: couldBeEmptyString !== "" ? couldBeEmptyString : null,
}

of course you could use the falsy values with or

const propertyDict = {
  aa ?: null,
  bb ?: undefined,
  cc ?:  couldBeZero  || null, //doesn't added if couldBeZero is null or falsy(0, "")
  dd ?: couldBeFalse || null,
  ee ?: couldBeEmptyString || null,
}

if you don't intend to remove falsy values from the object but still don't want null properties

const propertyDict= {
  aa ?: null,
  bb ?: undefined,
  cc ?: couldBeZeroOrNull,
  dd ?: couldBeFalseOrNull,
  ee ?: couldBeEmptyStringOrNull,
}

why is for me a concern currently(I always had this need, but I will show a current use case).

Suppose you want to filter from a collection in mongodb you will use Collection#find method, you pass an object as your first parameters to filter out the collection.

function filterPosts({ categoryId, postType }){
  // if non of them is present(==null) I want to get all the Posts
  // if either of them is present I want to use them as the filter
  // currently I have to go like this
  const query = {
    ...(categoryId? {categoryId} : {}),
    ...(postType? {postType} : {})
  }
  /* but normally I could forget and just do this
  const query = {
    categoryId,
    postType,
  }

  If you pass null in one of the properties, the database will perform an equality
  comparison to null and will return nothing if both are null. That's why I need to
  remove properties with null values before sending the query.
  */
  return db.collection('Posts').find(query)
}

is better to have a null check there

function filterPosts({categoryId, postType}){
  return db.collection('Posts').find({ categoryId?, postType? })
}
# Rodrigo Carranza (9 months ago)

I was about to hit send on a post also suggesting a helper function, but after thinking about it a bit more, Rodrigo's suggestion resembles extending the optional chaining proposal tc39/proposal-optional-chainingtc39/proposal-optional-chaining into the object literal notation. I suggest using the same character pair, "?.", as is proposed for optional chaining, instead of just "?".

let ret = {
    couldBeNull?.,
    bar?.: couldBeNull
}

The helper function might be best in the case where an empty string value needs the same treatment as null or undefined.

That proposal is awesome, but I think the real operator here is the ?, in combination with the chaining operator ?. but it could be anything with the same semantics ?: for objects ?. for chaining ?= for assignment ?? binary comparison. Just like in Dart but with extended functionality.

# Naveen Chawla (9 months ago)

What is the end goal of this proposal? To reduce the size of a serialized JSON? I can't see any other use for it. If that's the case, then perhaps a stringify that skips undefineds and nulls is more appropriate. Otherwise, what is the purpose / example case where this would be useful?

# Naveen Chawla (8 months ago)

Sounds like if you just use undefined instead of null, your mongodb case will work