Checking for null when calling a function in JavaScript shortcut? - javascript

Is there a shorter way to check for null when calling a function in JavaScript? (besides removing the curly braces). I always do the following for safety.
if (errorNotificationFn) {
errorNotificationFn(errorString);
}
I like the ?? operator and was wondering if there is something similar for function calls.

Yes, you can use optional chaining which was brought in at the same time the nullish coalescing operator you mentioned was:
errorNotificationFn?.(errorString);
// −−−−−−−−−−−−−−−−^^
It's not just for function calls, it also short-circuits property evalution, for instance:
example = this?.that?.theOther?.();
will either A) set example to undefined if this, that, or theOther is either null or undefined, or B) set example to the result of calling this.that.theOther().
Works with brackets, too:
value = object["example"]?.something;
In that, if object["example"] is null or undefined, value receives undefined; otherwise, it receives the value from object["example"].something.

Related

Will the Logical nullish Assignment or nullish coalescing evaluate the assigned value in a non null case?

I want to understand if my use case will benefit from the logical nullish assignment operator.
I'm checking my database to see it some data exists, otherwise I fetch it from an API, however I don't want to fetch the data from the API if the data already exists in my database, I'm describing the scenario with some code below.
let myData = await Database.getData(); // will return null if the data doesn't exist
myData ??= await fetch("API"); // does this API call get executed even if myData is non null?
Just to clarify, I'm wondering if the API call is executed, even though it might return the database data.
Does using nullish coalescing instead make a difference, for such a scenario ?
I'm aware that I can use several methods including if-else for such a case, however I want to understand if these operators will for in such a scenario.
does this API call get executed even if myData is non-null?
No, it will not be executed.
myData ??= await fetch("API")
is equivalent to
myData ?? (myData = await fetch("API"))
So, only if the first expression myData is nullish, the second assignment part runs.
let value = "test"
value ??= null.toString() // doesn't throw error because it is not executed
console.log(value)
value = null
value ??= null.toString() // throws error
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.
The answer is no. details

JS optional chaining clarification

I found a really great use case for optional chaining in my react project. I have used it slightly before but this line of code has made me a bit confused.
I have a table that is sortable.
One of the columns shows success or failure depending on if failed_date is null or a date.
sortedRows = sortedRows.sort((a, b) => a?.failed_date?.localeCompare(b?.failed_date));
But What confuses me is which value does the '?.' check is nullish?
Does a.failed_date?.localeCompare() check if failed_date?. is null/undefined or does it check if ?.localeCompare() is null/undefined?
Same with b?.failed_date is it checking b to be nullish? or failed_date.
I think My confusion comes from looking at the Documentation
Because arr?.[50] checks if element 50 is nullish but obj.method?.() checks if the method is not nullish?
Looking at this second block of code (which I believe is now correct) a.failed_date may be nullish and won't do localeCompare if a.failed_date is null?
But what if a.failed_date is not null but b.failed_date is null?
Does localeCompare not care? I haven't gotten an error but I was using localeComapre(b?.failed_date)
sortedRows = sortedRows.sort((a, b) => a.failed_date?.localeCompare(b.failed_date));
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
Basically, the ? in that context means optional chaining.
How it works is, for example, if you define an object like below, and you want to try and access the views property, it will throw an error.
const obj = { website: "stackoverflow.com", };
console.log(obj.views.toFixed(0)); // Error!
This is because you are trying to access a method off of undefined, which doesn't have anything.
To avoid this error, we can use optional chaining, like below.
const obj = { website: "stackoverflow.com", };
console.log(obj?.views?.toFixed(0)); // undefined
Optional chaining tells JavaScript to complete the method/read the key, but if it doesn't exist, instead of throwing an error, just return undefined.
It also works with arrays; the same way! If, say, index 78 doesn't exist, instead of throwing an error, it will just return undefined.
const arr = [1, 2, 3];
console.log(arr?.[78]?.toString());
To elaborate here, it is possible to stack multiple optional chaining operators as seen in OP's code a?.failed_date?.localeCompare(b?.failed_date)
In these cases, it is not a question of which object key value will be checked. The code will be evaluated from left to right and if any of the object values are nullish then undefined will be returned.
Refer to the documentation for further understanding
MDN Optional Chaining

casting type using optional chaining in javascript

we can safety access to deeper level of object by doing
data?.user?.age
but can I do casting at the same line?
const ageInNumber = +data?.user?.age!
typescript doesn't throw error but I'm not sure it won't give me trouble.
The optional chaining operator (?.) returns undefined if its first operand is null or undefined.
Casting undefined to a number won't raise any exceptions, just silently returns NaN. If that's acceptable to you, then that part is OK.
However, the non-null assertion (!) is problematic. According to this GitHub issue, TS evaluates a?.b! as (a?.b)!, asserting the entire chain, not just the .b part. So:
If none of the parts may ever be nullish, then the ?.'s are superfluous, and you should replace them with regular property access (.) to increase clarity.
If any of the parts can be nullish, it will short-circuit with undefined, and the non-null assertion is violated. If that's the case, you should remove the assertion.
However, if the last part (i.e. the age property of data.user) can be null (not undefined), then the entire chain returns null, which casts to 0, therefore is indistinguishable from a real zero received in the data. To make it NaN too (or set a default value), you can use the nullish-coalescing operator (??):
const ageInNumber = +(data?.user?.age ?? NaN)

Using the || (or operator) outside of if statements [duplicate]

This question already has answers here:
Javascript: || instead of IF statement - is this legal and cross browser valid?
(10 answers)
Closed 6 years ago.
So I'm reading Airbnb's JS styleguide and I don't understand what the OR operator is doing in the following example. More specifically in the Jedy constructor options || (options = {}); Is basically creating an empty object if no arguments were passed to the constructor? Therefore, the name property of the Jedi constructor would be set to 'no name'?
function Jedi(options) {
options || (options = {});
this.name = options.name || 'no name';
}
Jedi.prototype.getName = function getName() {
return this.name;
};
Jedi.prototype.toString = function toString() {
return 'Jedi - ' + this.getName();
};
PS. It seems like there are a lot shorthand ways of doing things with JS. Are there any good resources or articles explaining what these are and when it's best to use them?
The || operator takes two arguments. If the first argument is a "truthy" value, it returns the first argument; otherwise, it returns the second. It also short-circuits; that is, if the first argument is truthy it does not evaluate the second. If the second argument is an expression with side effects, this can be very significant.
The statement options || (options = {}); relies on this. If options is truthy, then the assignment expression will not be evaluated. If it is falsy, then the second expression will be evaluated.
Now, this is functional equivalent to the statement options = options || {};. In theory, that statement could be slightly slower, because it will assign options to itself rather than simply not assigning anything. However, the effect of this is negligible.
Js logical operators return not true or false, but truly or falsy value itself. For example in expression x && y, if x is falsy, then it will be returned, otherwise y will be returned. So the truth table for operator is correct.
The same for ||. It's a good way for specifying function default values.
You will often find this code in JavaScript plugins it basically means if an object with name options does not exists create a new one
If you try to access a property on options like
options.name and options does not exists then it will give you an error that options is undefined.But with this options || (options = {}) code you can always ensure that the JavaScript Object you are accessing always exists.
I will check if I could provide you some links for this to read about.
This is a good supporting link
How can I create an empty namespace object without overwriting another object with the same name?
seems like this is a more concise way of checking that the object exists and assigning it the value of an empty object if it does not. It isn't all that clear though. A little clearer implementation would be
var options = options || {};
even better, use es2015 default parameters
function Jedi(options = {}) {
this.name = options.name || 'no name';
}
In many (most) programming languages, at runtime unnecessary executions are optimized away. ||binary operator returns true if either of its operands evaluate to true. Since both the operands are serially evaluated, if the first one evaluates to true, the outcome of || operator is going to be true. so the second operand need not be evaluated. If the first one returns false, then second one decides what the result of || operator is going to be. this is the behavior that is being exploited here.
if options is set to non null value, it will evaluate to true. So don't execute the second operand which initializes it to empty object. on the next line if options.name is not null, then initialize it to 'no name'

explaining this declaration of the global namespace

I see this quite a lot at the top of scripts but I'm not completely sure what it means, can anyone explain?
var whatevername = whatevername || {};
It uses the OR operator to set default values. If whatevername has been set it will be used, otherwise a new empty object will be used.
An example:
function sayHi(options){
options = options || {};
if (options.useAlert){
alert("hi");
} else {
console.log("hi");
}
}
In this case you can always use the options parameter, even if it isn't passed to the function:
sayHi();
sayHi({"useAlert": true});
In the first case {} will be used and options.useAlert will be undefined. In the if statement that's the same as it being set to false and console.log will be used to print.
The OR operator is usually used like this:
if (hasAnEmailAddress || hasAPhoneNumber) {contactPerson()}
If hasAnEmailAddress is true the operator will return the value of hasAnEmailAddress instead of hasAPhoneNumber. If it isn't true the value of the second argument, hasAPhoneNumber will be returned.
That logic is used when setting default values: If the first argument is falsy return the second argument - even if it isn't a boolean value.
it initializes whatevername with an empty object if whatevername hasn't already been initialized.
Equivalent code
if(!whatevername) whatevername = {}
In a lot of languages, you will see this done with a ternary operator, which I think makes it very clear what's going on. Example:
var whatevername = (whatevername != NULL) ? whatevername : {};
In Javascript, if the || operator evaluates to truthy, it will not return a boolean value as one might expect, but the value of the operand which was last evaluated. Therefor, if whatevername is null, it will return a new object, otherwise it will return whatevername. Ruby does this as well, just to name another example of this behaviour.
This is a default value statement. || is the symbol for OR, as you probably know.
The statement reads "set whatevername to whatevername OR an empty object". The OR will pick the first of the two objects that reads to a truthy value (not empty, not false). If whatevername was set, you'll get whatevername. If not (or if set to null), you'll get an empty object.

Categories