Understanding New Javascript Ternary Condition Convention - javascript

I don't know this condition convention in JS(!params?.q). I know the ternary condition but I don't understand this. Can anyone provide insights on this or what should I learn to understand similar conventions?
JS Code Block
if (!params?.q) {// I don't understand a '?' without a ternary //condition
setSkipFirstRender(false);
setSort({
name: PersonEnum.keys.displayName,
dir: PersonEnum.sortOrder.asc,
});
}

The ?. operator is the optional chaining operator, sometimes also called the Elvis operator.
Despite both using the ? character, the optional chaining operator and ternary statements serve two different purposes.
Normally if you were to access params.q and params was null or undefined, an error would be thrown. What the optional chaining operator allows you to do is safely attempt to access the q property without an error being thrown. In this case, if params were null or undefined, params?.q would evaluate to undefined.
Essentially this is equivalent to checking if(!(params && params.q)).
You can read more about the optional chaining operator at https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

Related

What does the myObj.param?.otherParam operator do and how is it used?

I was reading the fundamentals guide for React Navigation and in the section for passing parameters to routes I came across this bit of code that I've never seen before.
if (route.params?.post) {
// Do something
}
I've never seen the ? operator used that way, I've only used the ternary operator. When searching the only other thing I found is the nullish assignment operator ??=.
I fiddled with it in the console and it seems to check if param exists so that if it doesn't exist it doesn't error when asking for .post
My first thought was that is a ternary operator without the second argument, but the third argument appears to be required.
So my question is, in the above code block, what is the ? doing, what is that called, and how/when is it used?
Thanks
It's called optional chaining. You can use it to check if the preceding variable is null, so that you could spare yourself checking for null/undefined properties.
// want to access blub.test.smth
if(blub && blub.test) {
// possibly access blub.test.smth
const value = blub.test.smth;
}
vs
const value = blub?.test?.smth

What does this JavaScript expression mean?

I am working with react-navigation and I can't figure out the meaning of this syntax.
React.useEffect(() => {
if (route.params?.post) { <<<<<WHAT IS THIS ?
// Post updated, do something with `route.params.post`
// For example, send the post to the server
}
}, [route.params?.post]);
Does it work like obect.doesPropertyExist.subProperty or something else?
I have tried going through MDN documentation but can't find any reference to this type of syntax. I am not able to use similar syntax on a random object in my node REPL.
It is called Optional Chaining. Provided in MDN doc:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining
The optional chaining operator (?.) permits reading the value of a
property located deep within a chain of connected objects without
having to expressly validate that each reference in the chain is
valid. The ?. operator functions similarly to the . chaining operator,
except that instead of causing an error if a reference is nullish
(null or undefined), the expression short-circuits with a return value
of undefined. When used with function calls, it returns undefined if
the given function does not exist.
if(route.params.post) then do something.
It checks if route.params has object post
It's called Optional Chaining operator. And it's shorthand for
route.params && route.params.post

is there any equivalent for PHP's "??" operation in javascript? [duplicate]

This question already has answers here:
Null-safe property access (and conditional assignment) in ES6/2015
(11 answers)
Closed 2 years ago.
I've been programming a lot in Swift recently. Today I did some work in JavaScipt when question popped up to me:
Is there something similar to optional chaining in JavaScript? A way to prevent undefined is not an object without any variables?
Example:
function test(){
if(new Date() % 2){
return {value: function(){/*code*/}};
}
}
test().value();
will fail half of time because sometimes test returns undefined.
The only solution I can think of is a function:
function oc(object, key){
if(object){
return object[key]();
}
}
oc(test(), 'value');
I would like to be able to do something like:
test()?.value()
The part after the question mark is only executed if test returned an object.
But this is not very elegeant. Is there something better? A magic combination of operators?
Edit I know I could rewrite test to return something. But I'm wondering if there's something like optional chaining. I'm not interested in a particular solution to the above example. Something that I also can use if have no control over the function returning undefined.
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
In plain JavaScript you have to do type checks or structure your code so that you know an object will exist.
CoffeeScript, a language that compiles down to JavaScript, provides an existential operator ?. for safe chaining if you're willing to consider a preprocessed language.
There's another discussion here about why you can't reproduce this behavior in JS.
There is also a discussion on the ESDiscuss forums about adding an existential operator to a future version of JavaScript. It doesn't seem very far along though, certainly nowhere close to practical use. More of an idea at this point.
Optional chaining has landed in JS. We can use optional chaining via the ?. operator in object property access. It allows us to try accessing properties of objects which might not exists (i.e. are undefined) without throwing an error.
Here is a code example:
const obj = {
foo: {
bar: 1
}
};
// If we try to access property which doesn't exists
// it just returns undefined
console.log(obj.baz);
try {
// Now we try to access a property of undefined which throws an error
obj.baz.foz;
} catch (e) {
console.dir(e.message);
}
// Now we use the optional chaining operator ?.
// We get undefined instead of an error
console.log(obj.baz?.foz);
console.log(obj.foo?.bar);
You can use
test() && test().value();
or
var testResult = test();
testResult && testResult.value();
If you ask me this is most similar to Swift's optional chaining.
var Obj = {Prop: {name: 'peter'}}
console.log(Obj.Prop.name)
console.log(Obj?.Prop?.name)
In the first sentence, you're just accessing object properties. The problem with that is that if you find Prop to be something other than an object, it will throw an exception. That's the reason of the optional chainig operator.
Lets say you try to do Obj.Prop2.name.
You'll get Uncaught TypeError: Cannot read property 'name' of undefined
if Instead you did Obj.Prop2?.name, You'll only receive undefined as a value, instead of an exception.
This is particularly useful when accessing deeply nested properties.
WARNING: This is a relatively new JS feature that's not yet implemented in all browsers, so be careful while using it for production applications.
Optional Chaining is finally in the JavaScript standard!
Here are a few examples:
// properties
foo?.bar
foo?.bar()
foo?.bar.baz()
foo?.bar?.baz()
// indexing
foo?.[0]
foo?.['bar']
// check if a function is defined before invoking
foo?.()
foo.bar?.()
foo?.bar?.()
And this is way better than what most people use for manually checking for nulls
Instead of evaluating
foo?.bar
to this little code snippet we are all used to writing
foo ? foo.bar : null
it actually evaluates to
foo == null ? undefined : foo.bar
which works for all the falsey values like an empty string, 0 or false.
Unrelated to the question, but you might also be interested in the ?? operator.
It has a similar purpose as || except it only checks for null or undefined.
For example:
foo ?? bar
would be the same as:
foo != null ? foo : bar
This is a very new feature, so even thought a lot of users already use a browser that supports this you will still want to use a tool to convert it to an older version of javascript.
What about returning a noop function that does nothing when the condition isn't met?
function test(){
if(new Date() % 2){
return {value: function(){/*code*/}};
}
return {value: function(){ /* just return a type consistent with the function above */ }
}
You can always return this; if test is a object method.
But why do you want to prevent such errors by creating mock functions?

heroForm.errors?.xxx in angular forms template

Why do we have a question mark in a property? What is '?' marks significance.
<div *ngIf="heroForm.errors?.identityRevealed && (heroForm.touched || heroForm.dirty)" class="cross-validation-error-message alert alert-danger">
Name cannot match alter ego.
</div>
That is not a Typescript operator this is safe navigation operator or elvis operator.
Angular 2 has a safe navigation operator in templates.
? "Question Mark" is not a ternary operator in typescript, ? is used for safe loading the HTML doc while a component is generating the DOC for browser display.
Safe Navigation Operator (Elvis Operator):
The Safe Navigation Operator is also known as the "Elvis Operator". This operator is very useful to protect against null and undefined values in property paths. This operator allows us to navigate an object path in situations when we are not aware whether a path exists or not. It returns value of the object path if it exists, else it returns the null value. It is very useful to prevent null-reference exceptions.
Syntax:
object?.path
Refer:https://www.c-sharpcorner.com/article/introduction-to-safe-navigation-operator-in-angular-2/

Unconditional use of conditional expression for default assignment

I'm getting the following linting error: Unconditional use of conditional expression for default assignment
What is wrong with the below?
(myOverride) ? myOverride : MAGIC_HOST,
Where if myOverride is defined I want to use myOverride, if it is not defined I want to use the env var MAGIC_HOST.
Apparently you're using ESLint (as that error is an ESLint) error. It's because of the no-unneeded-ternary rule which is meant to flag up unnecessary use of the conditional operator (they call it the "ternary")¹. From the linked docs:
Another common mistake is using a single variable as both the conditional test and the consequent. In such cases, the logical OR can be used to provide the same functionality. Here is an example:
// Bad
var foo = bar ? bar : 1;
// Good
var foo = bar || 1;
So the rule is telling you to use myOverride || MAGIC_HOST instead.
You don't have to, the code you've shown isn't wrong. It's just it doesn't pass that ESLint rule.
¹ "they call it the 'ternary'" - The conditional operator is a ternary operator (an operator accepting three operands, just like * is a binary operator — an operator accepting two operands). And it is, for now, the only ternary operator JavaScript has. But that doesn't necessarily always have to be true as the language evolves. It's correctly called the conditional operator.
It is not inherently wrong, but it is better written as:
myOverride || MAGIC_HOST
as explained here.

Categories

Resources