I"m trying the new JavaScript Optional Chaining syntax and it seems that it has an issue with methods which has no return value. For example:
I have a restaurant object with order method in it:
const restaurant = {
order(i, k) {
console.log(`I was here with ${i} and ${k}`);
// does not return value
}
};
Now if i try to check if the order method exist inside restaurant object like below, it returns 'undefiend':
const orderCheck = restaurant.order?.(0, 1);
console.log(orderCheck ); // it returns undefined
Now the problem is, if i use above case with Nullish Coalescing Operator like below, it does not work:
console.log(restaurant.order?.(0, 1) ?? 'Method does not exist');
Output:
I was here with 0 and 1
Method does not exist
ISSUE: Now the issue in above statement is, the optional chaining syntax even finds the order method & prints "I was here with 0 and 1" but still returns 'undefiend' which makes Nullish Coalescing Operator to proceed and even it prints 'Method does not exist' too as default value?
Now, if i allow the order method to return a value then it works fine with Nullish Coalescing Operator and it does not proceed.
const restaurant = {
order(i, k) {
console.log(`I was here with ${i} and ${k}`);
return '1';
}
};
If check again:
console.log(restaurant.order?.(0, 1) ?? 'Method does not exist');
Output:
I was here with 0 and 1
Is it necessary for optional chaining syntax to expect a return value other than nullish values from a method in order to check its availability?
In above case, the order method does exist then How to prevent Nullish Coalescing Operator to not to proceed for the default 'Method does not exist'?
I'm testing it with modern browsers (Chrome & firfox) and i have also enabled the javaScript experimental features in Chrome but it still work the same above way.
Any thoughts would be helpful? Thanks
CodePudding user response:
This is not related to optional chaining.
The
Nullish Operator
returns its right-hand side operand when its left-hand side operand is null or undefined, and otherwise returns its left-hand side operand.
Therefore, the optional chaining is already working as the function exists but its return value is undefined
, hence the operator goes to the right part.
Note:
- the log inside the function is showing as it's getting executed first but no value is being returned.
- if function didn't exist, in this case it will also compute to
undefined
due to theoptional chaining
so the right side of thenullish operator
would be taken as well
let obj = {};
console.log("function doesn't exist", obj?.foo?.(), obj?.foo?.() ?? 'right');
obj = { foo: () => {} };
console.log("function exists but doesn't return", obj?.foo?.(), obj?.foo?.() ?? 'right');
obj = { foo: () => { return 'left'; } };
console.log("function exists and returns", obj?.foo?.(), obj?.foo?.() ?? 'right');
Edit: to prevent Nullish Coalescing Operator to not proceed for the default 'Method does not exist' Even the method exist
obj = { foo: () => {} };
console.log(obj?.foo && typeof obj.foo === 'function' ? obj.foo() : 'right');
CodePudding user response:
With restaurant.order?.(0, 1)
you check if the method exists, and if it does, then call it and return the result of the call. In your case, order(0, 1)
returns undefined, therefore restaurant.order?(0, 1)
also returns undefined.