Replace a value if null or undefined in JavaScript
JavascriptJavascript Problem Overview
I have a requirement to apply the ??
C# operator to JavaScript and I don't know how.
Consider this in C#:
int i?=null;
int j=i ?? 10;//j is now 10
Now I have this set up in JavaScript:
var options={
filters:{
firstName:'abc'
}
};
var filter=options.filters[0]||'';//should get 'abc' here, it doesn't happen
var filter2=options.filters[1]||'';//should get empty string here, because there is only one filter
How do I do it correctly?
Thanks.
EDIT: I spotted half of the problem: I can't use the 'indexer' notation to objects (my_object[0]
). Is there a way to bypass it? (I don't know the names of the filters properties beforehand and don't want to iterate over them).
Javascript Solutions
Solution 1 - Javascript
Here’s the JavaScript equivalent:
var i = null;
var j = i || 10; //j is now 10
Note that the logical operator ||
does not return a boolean value but the first value that can be converted to true.
Additionally use an array of objects instead of one single object:
var options = {
filters: [
{
name: 'firstName',
value: 'abc'
}
]
};
var filter = options.filters[0] || ''; // is {name:'firstName', value:'abc'}
var filter2 = options.filters[1] || ''; // is ''
That can be accessed by index.
Solution 2 - Javascript
ES2020 Answer
The new Nullish Coalescing Operator, is finally available on JavaScript. However, do take note of the browser support. You may need to use a JavaScript compiler like Babel to convert it into something more backward compatible.
According to the documentation,
> The nullish coalescing operator (??) is a logical operator that > returns its right-hand side operand when its left-hand side operand is > null or undefined, and otherwise returns its left-hand side operand.
const options={
filters:{
firstName:'abc'
}
};
const filter = options.filters[0] ?? '';
const filter2 = options.filters[1] ?? '';
This will ensure that both of your variables will have a fallback value of ''
if filters[0]
or filters[1]
are null
, or undefined
.
Do take note that the nullish coalescing operator does not return the default value for other types of falsy value such as 0
and ''
. If you wish to account for all falsy values, you should be using the OR operator ||
.
Solution 3 - Javascript
Logical nullish assignment, 2020+ solution
A new operator has been added, ??=
. This is equivalent to value = value ?? defaultValue
.
||=
and &&=
are similar, links below.
This checks if left side is undefined or null, short-circuiting if already defined. If not, the left side is assigned the right-side value.
Basic Examples
let a // undefined
let b = null
let c = false
a ??= true // true
b ??= true // true
c ??= true // false
// Equivalent to
a = a ?? true
Object/Array Examples
let x = ["foo"]
let y = { foo: "fizz" }
x[0] ??= "bar" // "foo"
x[1] ??= "bar" // "bar"
y.foo ??= "buzz" // "fizz"
y.bar ??= "buzz" // "buzz"
x // Array [ "foo", "bar" ]
y // Object { foo: "fizz", bar: "buzz" }
Functional Example
function config(options) {
options.duration ??= 100
options.speed ??= 25
return options
}
config({ duration: 555 }) // { duration: 555, speed: 25 }
config({}) // { duration: 100, speed: 25 }
config({ duration: null }) // { duration: 100, speed: 25 }
??= Browser Support Sept 2021 - 90%
Solution 4 - Javascript
>I spotted half of the problem: I can't use the 'indexer' notation to objects (my_object[0]). Is there a way to bypass it?
No; an object literal, as the name implies, is an object, and not an array, so you cannot simply retrieve a property based on an index, since there is no specific order of their properties. The only way to retrieve their values is by using the specific name:
var someVar = options.filters.firstName; //Returns 'abc'
Or by iterating over them using the for ... in
loop:
for(var p in options.filters) {
var someVar = options.filters[p]; //Returns the property being iterated
}
Solution 5 - Javascript
TLDR:
int j=i ?? 10;
is perfectly fine to use in javascript also. Just replace int
with let
.
??
vs ||
??
should be preferred to ||
because it checks only for nulls and undefined.
All The expressions below are true:
(null || 'x') === 'x' ;
(undefined || 'x') === 'x' ;
//Most of the times you don't want the result below
('' || 'x') === 'x' ;
(0 || 'x') === 'x' ;
(false || 'x') === 'x' ;
//-----
//Using ?? is preferred
(null ?? 'x') === 'x' ;
(undefined ?? 'x') === 'x' ;
//?? works only for null and undefined, which is in general safer
('' ?? 'x') === '' ;
(0 ?? 'x') === 0 ;
(false ?? 'x') === false ;
Asterisk: Check browser compatibility and if you really need to support these other browsers use babel.
Solution 6 - Javascript
Destructuring solution
Question content may have changed, so I'll try to answer thoroughly.
Destructuring allows you to pull values out of anything with properties. You can also define default values when null/undefined and name aliases.
const options = {
filters : {
firstName : "abc"
}
}
const {filters: {firstName = "John", lastName = "Smith"}} = options
// firstName = "abc"
// lastName = "Smith"
> NOTE: Capitalization matters
If working with an array, here is how you do it.
In this case, name is extracted from each object in the array, and given its own alias. Since the object might not exist = {}
was also added.
const options = {
filters: [{
name: "abc",
value: "lots"
}]
}
const {filters:[{name : filter1 = "John"} = {}, {name : filter2 = "Smith"} = {}]} = options
// filter1 = "abc"
// filter2 = "Smith"
Browser Support 92% July 2020