JavaScript check if value is only undefined, null or false - javascript

Other than creating a function, is there a shorter way to check if a value is undefined,null or false only in JavaScript?
The below if statement is equivalent to if(val===null && val===undefined val===false)
The code works fine, I'm looking for a shorter equivalent.
if(val==null || val===false){
;
}
Above val==null evaluates to true both when val=undefined or val=null.
I was thinking maybe using bitwise operators, or some other trickery.

Well, you can always "give up" :)
function b(val){
return (val==null || val===false);
}

The best way to do it I think is:
if(val != true){
//do something
}
This will be true if val is false, NaN, or undefined.

I think what you're looking for is !!val==false which can be turned to !val (even shorter):
You see:
function checkValue(value) {
console.log(!!value);
}
checkValue(); // false
checkValue(null); // false
checkValue(undefined); // false
checkValue(false); // false
checkValue(""); // false
checkValue(true); // true
checkValue({}); // true
checkValue("any string"); // true
That works by flipping the value by using the ! operator.
If you flip null once for example like so :
console.log(!null) // that would output --> true
If you flip it twice like so :
console.log(!!null) // that would output --> false
Same with undefined or false.
Your code:
if(val==null || val===false){
;
}
would then become:
if(!val) {
;
}
That would work for all cases even when there's a string but it's length is zero.
Now if you want it to also work for the number 0 (which would become false if it was double flipped) then your if would become:
if(!val && val !== 0) {
// code runs only when val == null, undefined, false, or empty string ""
}

One way to do it is like that:
var acceptable = {"undefined": 1, "boolean": 1, "object": 1};
if(!val && acceptable[typeof val]){
// ...
}
I think it minimizes the number of operations given your restrictions making the check fast.

Another solution:
Based on the document, Boolean object will return true if the value is not 0, undefined, null, etc. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Boolean
If value is omitted or is 0, -0, null, false, NaN, undefined, or the empty string (""), the object has an initial value of false.
So
if(Boolean(val))
{
//executable...
}

only shortcut for something like this that I know of is
var val;
(val==null || val===false) ? false: true;

Boolean(val) === false. This worked for me to check if value was falsely.

Using ? is much cleaner.
var ? function_if_exists() : function_if_doesnt_exist();

Try like Below
var Boolify = require('node-boolify').Boolify;
if (!Boolify(val)) {
//your instruction
}
Refer node-boolify

Related

shortcut to check if variable is null || undefined||empty string||false

I am looking for check, if my variable is one of : null || undefined || empty string || false
Right now its look messy and long:
const userHasPhoneNumber = user.phone === undefined ||
user.phone === "" ||
user.phone === false ||
user.phone === null ? false : true;
Is there shortcut?
You can shortcut x === undefined || x === null to x == null. For the others, there is no shortcut as there are some falsy number values as well. You could however do
const userHasPhoneNumber = typeof user.phone == "number" || !!user.phone
If you coerce that string to a boolean then it should check all your conditions, which is pretty much checking if user.phone is truthy.
It depends how you want to use it. If you wanted to use it in a condition, i.e. if(userHasPhoneNumber) ... then you can use the string directly : if(user.phone) as it will coerce to a boolean.
If you really need to have a boolean variable then need to cast it to a boolean explicitely:
Either through
const userHasPhoneNumber = Boolean(user.phone);
or
const userHasPhoneNumber = !!user.phone;
Note, as #Bergi commented, that there are more values that are coerced to a false value (falsy values), for example NaN or the number 0 (the string "0" will coerce to true), so it depends what your input is. If it's never a number but either a string/boolean/null/undefined, it should be fine. Here is the list of all falsy values for reference : https://developer.mozilla.org/en-US/docs/Glossary/Falsy
Use JavaScript's !!, witch will become false for null, "", undefined and false:
const user = {
phone_1: null,
phone_2: "",
phone_3: undefined,
phone_4: false
};
console.log(!!user.phone_1); // false
console.log(!!user.phone_2); // false
console.log(!!user.phone_3); // false
console.log(!!user.phone_4); // false
Note Use this with caution as some results may be different then expected, this answer shows a complete list.

toBe(true) vs toBeTruthy() vs toBeTrue()

What is the difference between expect(something).toBe(true), expect(something).toBeTruthy() and expect(something).toBeTrue()?
Note that toBeTrue() is a custom matcher introduced in jasmine-matchers among other useful and handy matchers like toHaveMethod() or toBeArrayOfStrings().
The question is meant to be generic, but, as a real-world example, I'm testing that an element is displayed in protractor. Which matcher should I use in this case?
expect(elm.isDisplayed()).toBe(true);
expect(elm.isDisplayed()).toBeTruthy();
expect(elm.isDisplayed()).toBeTrue();
What I do when I wonder something like the question asked here is go to the source.
toBe()
expect().toBe() is defined as:
function toBe() {
return {
compare: function(actual, expected) {
return {
pass: actual === expected
};
}
};
}
It performs its test with === which means that when used as expect(foo).toBe(true), it will pass only if foo actually has the value true. Truthy values won't make the test pass.
toBeTruthy()
expect().toBeTruthy() is defined as:
function toBeTruthy() {
return {
compare: function(actual) {
return {
pass: !!actual
};
}
};
}
Type coercion
A value is truthy if the coercion of this value to a boolean yields the value true. The operation !! tests for truthiness by coercing the value passed to expect to a boolean. Note that contrarily to what the currently accepted answer implies, == true is not a correct test for truthiness. You'll get funny things like
> "hello" == true
false
> "" == true
false
> [] == true
false
> [1, 2, 3] == true
false
Whereas using !! yields:
> !!"hello"
true
> !!""
false
> !![1, 2, 3]
true
> !![]
true
(Yes, empty or not, an array is truthy.)
toBeTrue()
expect().toBeTrue() is part of Jasmine-Matchers (which is registered on npm as jasmine-expect after a later project registered jasmine-matchers first).
expect().toBeTrue() is defined as:
function toBeTrue(actual) {
return actual === true ||
is(actual, 'Boolean') &&
actual.valueOf();
}
The difference with expect().toBeTrue() and expect().toBe(true) is that expect().toBeTrue() tests whether it is dealing with a Boolean object. expect(new Boolean(true)).toBe(true) would fail whereas expect(new Boolean(true)).toBeTrue() would pass. This is because of this funny thing:
> new Boolean(true) === true
false
> new Boolean(true) === false
false
At least it is truthy:
> !!new Boolean(true)
true
Which is best suited for use with elem.isDisplayed()?
Ultimately Protractor hands off this request to Selenium. The documentation states that the value produced by .isDisplayed() is a promise that resolves to a boolean. I would take it at face value and use .toBeTrue() or .toBe(true). If I found a case where the implementation returns truthy/falsy values, I would file a bug report.
Disclamer: This is just a wild guess
I know everybody loves an easy-to-read list:
toBe(<value>) - The returned value is the same as <value>
toBeTrue() - Checks if the returned value is true
toBeTruthy() - Check if the value, when cast to a boolean, will be a truthy value
Truthy values are all values that aren't 0, '' (empty string), false, null, NaN, undefined or [] (empty array)*.
* Notice that when you run !![], it returns true, but when you run [] == false it also returns true. It depends on how it is implemented. In other words: (!![]) === ([] == false)
On your example, toBe(true) and toBeTrue() will yield the same results.
In javascript there are trues and truthys. When something is true it is obviously true or false. When something is truthy it may or may not be a boolean, but the "cast" value of is a boolean.
Examples.
true == true; // (true) true
1 == true; // (true) truthy
"hello" == true; // (true) truthy
[1, 2, 3] == true; // (true) truthy
[] == false; // (true) truthy
false == false; // (true) true
0 == false; // (true) truthy
"" == false; // (true) truthy
undefined == false; // (true) truthy
null == false; // (true) truthy
This can make things simpler if you want to check if a string is set or an array has any values.
var users = [];
if(users) {
// this array is populated. do something with the array
}
var name = "";
if(!name) {
// you forgot to enter your name!
}
And as stated. expect(something).toBe(true) and expect(something).toBeTrue() is the same. But expect(something).toBeTruthy() is not the same as either of those.
As you read through the examples below, just keep in mind this difference
true === true // true
"string" === true // false
1 === true // false
{} === true // false
But
Boolean("string") === true // true
Boolean(1) === true // true
Boolean({}) === true // true
1. expect(statement).toBe(true)
Assertion passes when the statement passed to expect() evaluates to true
expect(true).toBe(true) // pass
expect("123" === "123").toBe(true) // pass
In all other cases cases it would fail
expect("string").toBe(true) // fail
expect(1).toBe(true); // fail
expect({}).toBe(true) // fail
Even though all of these statements would evaluate to true when doing Boolean():
So you can think of it as 'strict' comparison
2. expect(statement).toBeTrue()
This one does exactly the same type of comparison as .toBe(true), but was introduced in Jasmine recently in version 3.5.0 on Sep 20, 2019
3. expect(statement).toBeTruthy()
toBeTruthy on the other hand, evaluates the output of the statement into boolean first and then does comparison
expect(false).toBeTruthy() // fail
expect(null).toBeTruthy() // fail
expect(undefined).toBeTruthy() // fail
expect(NaN).toBeTruthy() // fail
expect("").toBeTruthy() // fail
expect(0).toBeTruthy() // fail
And IN ALL OTHER CASES it would pass, for example
expect("string").toBeTruthy() // pass
expect(1).toBeTruthy() // pass
expect({}).toBeTruthy() // pass
There are a lot many good answers out there, i just wanted to add a scenario where the usage of these expectations might be helpful. Using element.all(xxx), if i need to check if all elements are displayed at a single run, i can perform -
expect(element.all(xxx).isDisplayed()).toBeTruthy(); //Expectation passes
expect(element.all(xxx).isDisplayed()).toBe(true); //Expectation fails
expect(element.all(xxx).isDisplayed()).toBeTrue(); //Expectation fails
Reason being .all() returns an array of values and so all kinds of expectations(getText, isPresent, etc...) can be performed with toBeTruthy() when .all() comes into picture. Hope this helps.

Convert truthy or falsy to an explicit boolean, i.e. to True or False

I have a variable. Let's call it toto.
This toto can be set to undefined, null, a string, or an object.
I would like to check if toto is set to a data, which means set to a string or an object, and neither undefined nor null, and set corresponding boolean value in another variable.
I thought of the syntax !!, that would look like this:
var tata = !!toto; // tata would be set to true or false, whatever toto is.
The first ! would be set to false if toto is undefined or null and true else, and the second one would invert it.
But it looks a little bit odd. So is there a clearer way to do this?
I already looked at this question, but I want to set a value in a variable, not just check it in an if statement.
Yes, you can always use this:
var tata = Boolean(toto);
And here are some tests:
for (var value of [0, 1, -1, "0", "1", "cat", true, false, undefined, null]) {
console.log(`Boolean(${typeof value} ${value}) is ${Boolean(value)}`);
}
Results:
Boolean(number 0) is false
Boolean(number 1) is true
Boolean(number -1) is true
Boolean(string 0) is true
Boolean(string 1) is true
Boolean(string cat) is true
Boolean(boolean true) is true
Boolean(boolean false) is false
Boolean(undefined undefined) is false
Boolean(object null) is false
!!o is also shorthand of Boolean(o) and works exactly same.
(for converting truthy/falsy to true/false).
let o = {a: 1}
Boolean(o) // true
!!o // true
// !!o is shorthand of Boolean(o) for converting `truthy/falsy` to `true/false`
Note that

How can I check if a variable is not null and also a number?

I am using the following:
$scope.option.selectedSubject != null && !isNaN($scope.option.selectedSubject)
Can someone tell me if there is another way to check if a variable is a valid defined number? Is there some way I can do this with just one check or how can I create a function to do this check and then call that ?
maybe this function might help you :
function isANumber(x) {
return ((+x)===x);
}
This might be useful to know: A variable can only be null when somewhere in your script it's being assigned, it will never be null by default.
var foo; // undefined
foo = null;
// null could be returned by a function too, which is the most common use of null
As zzzzBov stated in his comment, "isNaN will check if the numeric representation of the value is NaN. this means that isNaN('500') is false, while isNaN('foo') is true."
As to answer your question, check this table:
!isNaN(undefined); // false
!isNaN(null); // true
!isNaN(); // false
!isNaN(''); // true <= Watch out for this one !
!isNaN('test'); // false
!isNaN('10'); // true
!isNaN(10); // true
If you want to make sure it's a number, you should use typeof, then if this is a string, check if it has a length. Wrapping this all in a function would create something like:
function isNumber (num) {
// Return false if num is null or an empty string
if (num === null || (typeof num === "string" && num.length === 0)) {
return false;
}
return !isNaN(num);
}
isNumber(undefined); // false
isNumber(null); // false
isNumber(); // false
isNumber(''); // false
isNumber('test'); // false
isNumber('10'); // true
isNumber(10); // true
This would do the trick if you care only about numeric presentation.
!isNaN($scope.option.selectedSubject + "")
Notice the + ""

How do you implement a guard clause in JavaScript?

I want to guard my functions against null-ish values and only continue if there is "defined" value.
After looking around the solutions suggested to double equal to undefined: if (something == undefined). The problem with this solution is that you can declare an undefined variable.
So my current solution is to check for null if(something == null) which implicetly checks for undefined. And if I want to catch addionalty falsy values I check if(something).
See tests here: http://jsfiddle.net/AV47T/2/
Now am I missing something here?
Matthias
The standard JS guard is:
if (!x) {
// throw error
}
!x will catch any undefined, null, false, 0, or empty string.
If you want to check if a value is valid, then you can do this:
if (Boolean(x)) {
// great success
}
In this piece, the block is executed if x is anything but undefined, null, false, 0, or empty string.
The only safe way that I know of to guard against really undefined variables (meaning having variable name that were never defined anywhere) is check the typeof:
if (typeof _someUndefinedVarName == "undefined") {
alert("undefined");
return;
}
Anything else (including if (!_someUndefinedVarName)) will fail.
Basic example: http://jsfiddle.net/yahavbr/Cg23P/
Remove the first block and you'll get:
_someUndefinedVarName is not defined
Only recently discovered using '&&' as a guard operator in JS. No more If statements!
var data = {
person: {
age: 22,
name: null
}
};
var name = data.person.name && doSomethingWithName(data.person.name);
Ternary to the rescue !
(i) =>
i == 0 ? 1 :
i == 1 ? 2 :
i == 2 ? 3 :
null

Categories

Resources