A way to prevent properties to be added to an object if they are null or undefined.
An HTML attachment was scrubbed... URL: esdiscuss/attachments/20171128/750cba12/attachment-0001
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
An HTML attachment was scrubbed... URL: esdiscuss/attachments/20171128/228d2cd2/attachment-0001
You can just use proxy with proper set trap.
Or feed it through JSON.parse( JSON.strinigfy( o ) ) which will delete undefined things; doesn't help with null.
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}}
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
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
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.
@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: ''
}));
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.
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? })
}
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.
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?
Sounds like if you just use undefined instead of null, your mongodb case will work
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