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/
Related
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
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
For deeply nested property access, is there a JS operator similar to the "optional chaining" operator which applies to all properties/methods/etc. to the right?
Consider an object with deep nesting, where some properties are null:
const sort = payload.meta.displayConfig.properties.search.sort;
// ^---null? ^---null? ^--null?
This can be handled with the optional-chaining operator:
const sort = payload.meta.displayConfig?.properties?.search?.sort;
But is there another operator where "all calls to the right" are handled as if they were preceded by the optional-chaining operator? Observe:
const sort = payload.meta.displayConfig?!.properties.search.sort;
// ^^---fictional nested-optional-chaining
// operator
In this example (with the fictional ?! nested-optional-chaining operator), if anything from displayConfig and onward to the right (properties, search) are null or undefined, then execution is short-circuited as if each property was preceded by ?.
Is there any discussion around adding such a feature?
The short answer is no. You have to put ?. between each segment if you want to make each segment safe against null/undefined values. And as far as I can tell from looking through the different proposals for ecmascript there hasn't been any discussion of an operator like you're talking about.
Before the optional chaining operator was a thing, many libraries would implemented their own ways to get an attribute in a safe way, some of which behave closer to what you're wanting. For example, in lodash you can do _.get(payload, 'meta.displayConfig.properties.search.sort') However, now that the optional chaining operator is a thing, I would prefer just using it between every segment instead of using these library functions.
This question already has answers here:
In Typescript, what is the ! (exclamation mark / bang) operator when dereferencing a member?
(5 answers)
Closed 3 years ago.
I've been seeing this creep up in a few places now but have not found any answers on it.
I'm curious what the '!' bang does in the angular syntax.
From the Angular documentation:
The non-null assertion operator ( ! )
As of Typescript 2.0, you can enforce strict null checking with the
--strictNullChecks flag. TypeScript then ensures that no variable is unintentionally null or undefined.
In this mode, typed variables disallow null and undefined by default.
The type checker throws an error if you leave a variable unassigned or
try to assign null or undefined to a variable whose type disallows
null and undefined.
The type checker also throws an error if it can't determine whether a
variable will be null or undefined at runtime. You may know that can't
happen but the type checker doesn't know. You tell the type checker
that it can't happen by applying the post-fix non-null assertion
operator (!).
The Angular non-null assertion operator (!) serves the same purpose in
an Angular template.
For example, after you use *ngIf to check that hero is defined, you
can assert that hero properties are also defined.
<!-- No hero, no text -->
<div *ngIf="hero">
The hero's name is {{hero!.name}}
</div>
When the Angular compiler turns your template into TypeScript code, it
prevents TypeScript from reporting that hero.name might be null or
undefined.
Unlike the safe navigation operator, the non-null assertion operator
does not guard against null or undefined. Rather it tells the
TypeScript type checker to suspend strict null checks for a specific
property expression.
You'll need this template operator when you turn on strict null
checks. It's optional otherwise.
Its called the "Non-null assertion operator" and has nothing todo with Angular perse, it is from typescript.
let s = e!.name; // Assert that e is non-null and access name
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.