How can I use optional chaining with arrays and functions?
You need to put a .
after the ?
to use optional chaining:
myArray.filter(x => x.testKey === myTestKey)?.[0]
Playground link
Using just the ?
alone makes the compiler think you're trying to use the conditional operator (and then it throws an error since it doesn't see a :
later)
Optional chaining isn't just a TypeScript thing - it is a finished proposal in plain JavaScript too.
It can be used with bracket notation like above, but it can also be used with dot notation property access:
const obj = {
prop2: {
nested2: 'val2'
}
};
console.log(
obj.prop1?.nested1,
obj.prop2?.nested2
);
JS optional chaining clarification
Let's say you define variable like below
const variable = { value: 'test' };
then you want to access variable?.value
it equals variable === null || variable === undefined ? undefined : variable.value
.
Same with array.
Check typescript playground and see js output https://www.typescriptlang.org/play?#code/MYewdgzgLgBAhgJwXAnjAvDA2gXQNwBQBiyKA-AHRYCsADDkA
Optional Chaining in JavaScript returns undefined instead of null when the variable to be tested is null
An optional chain does not evaluate to the nullish value on which the property was accessed, but to undefined
- just like you get undefined
when a property does not exist in an object.
Conceptually, think of person?.street
not as
person && person.street
but rather as
(person ?? {}).street
Though accurately (especially when chained further, since it does short-circuit instead of evaluating the rest of the chain) it's really
person != null ? person.street : undefined
See also the FAQ on the optional chaining proposal:
Why does
(null)?.b
evaluate toundefined
rather thannull
?Neither
a.b
nora?.b
is intended to preserve arbitrary information
on the base objecta
, but only to give information about the
property"b"
of that object. If a property"b"
is absent froma
,
this is reflected bya.b === undefined
anda?.b === undefined
.In particular, the value
null
is considered to have no properties;
therefore,(null)?.b
isundefined
.
Can Optional Chaining be alternative of 'in' operator in Javascript
AFAIK, in
is used to get to know whether the property exists in an object or its prototype or not.
const address = {
zipCode: 1234,
country: 'usa',
city: 'new York',
};
if ('zipCode' in address) {
console.log('This is address from in checking');
}
Optional chaining on the left side in Javascript
It's not possible, sorry.
In the interest of a canonical answer: The MDN documentation isn't explicit about this, but you can read the proposal's README in GitHub for more information. It says:
The following is not supported, although it has some use cases; see Issue #18 for discussion:
- optional property assignment:
a?.b = c
In the linked issue are the comments 1:
OK, seems like there's a rough agreement in this thread not to do the write case in the first iteration.
and 2:
We also discussed this question at TC39, and the committee did not seem so interested in adding this feature.
So I guess it's not likely to happen anytime soon.
Hope that helps; good luck!
Optional chaining on Array.find in JS
When you do:
({a:1})?.a = 10
What you are really doing is:
1 = 10
Which causes the same error as you have observed. So you cannot use optional chaining to set values.
Assuming you want to mutate the element of an array what you could do is use ??
to default to empty object in case Array#find
returns null
. If an element is found you can modify it, if not you're just assigning 50 to an object that is immediately discarded:
let myArray = [{name: "foo", value: 30}, {name: "abc", value: 40}];
(myArray.find(entry => entry.name === 'foo') ?? {}).value = 50;
What are alternative methods for left side optional chaining in Javascript?
You're looking for logical nullish assignment, the short form of x = x ?? y
:
(customer.details ??= {}).car = { make: 'Toyota' };
It also works nice with chaining, e.g.
((customer.details ??= {}).car ??= {}).make = 'Toyota';
Optional Chaining in JavaScript
This is currently a Stage 4 proposal you can check on the progress of it here:
https://github.com/tc39/proposal-optional-chaining
You can use the babel plugin today:
https://www.npmjs.com/package/babel-plugin-transform-optional-chaining
Update 11th January 2020:
Babel now supports optional chaining by default
https://babeljs.io/blog/2020/01/11/7.8.0
The Optional Chaining operator is spelled ?.
. It may appear in three positions:
obj?.prop // optional static property access
obj?.[expr] // optional dynamic property access
func?.(...args) // optional function or method call
Notes:
In order to allow foo?.3:0
to be parsed as foo ? .3 : 0
(as required for backward compatibility), a simple lookahead is added at the level of the lexical grammar, so that the sequence of characters ?.
is not interpreted as a single token in that situation (the ?.
token must not be immediately followed by a decimal digit).
Also worth checking out:
https://github.com/tc39/proposal-nullish-coalescing
https://github.com/babel/babel/tree/master/packages/babel-plugin-proposal-nullish-coalescing-operator
Related Topics
How to Get the Day of Week and the Month of the Year
Get All Attributes of an Element Using Jquery
Recursive Matching with Regular Expressions in JavaScript
How to Post Form Data with Fetch API
Js:Convert Array of Strings to Array of Objects
Differencebetween JavaScript Promises and Async Await
Do You Ever Need to Specify 'Javascript:' in an Onclick
JavaScript Variables Declare Outside or Inside Loop
Getting the Return Value of JavaScript Code in Selenium
JavaScript Thousand Separator/String Format
How to Return Values from Async Functions Using Async-Await from Function
Optional Chaining in JavaScript
Dangerous Implications of Allman Style in JavaScript
React-Router: No Not Found Route
Disable Submit Button on Form Submit
How to Strip All Punctuation from a String in JavaScript Using Regex