vue.js function only working if value is greater than zero - vue.js

I have the following function that is formating font colour based on the value returned. The value returned is from a GraphQl non-nullable field and is in a range from 0-10. It works perfectly if the value is 1-10, if the value is zero it does not run as expected.
formatFont: function (state) {
if (state) {
if (state >= 0 && state <= 6) {
return 'red--text';
} else if (state >= 7 && state <= 8) {
return 'orange--text';
} else if (state >= 9 && state <= 10) {
return 'green--text';
} else {
return 'white-text' // i.e. white on white = invisible
}
} else {
console.log('Output else')
return 'white--text' // i.e. white on white = invisible
}
}
If the value is zero it will return the else statement, I have a solution to increment each value by 1 which resolves but it feels like a hack, I want to understand why it doesn't recognise zero?

change
if (state) {
to
if (typeof state !== 'undefined') {
why because 0 is falsey

var a= 0
var b= '0'
var c= 1
if(a) {
console.info('a',a)
}
if(b){
console.info('b',b)
}
if(c){
console.info('c',c)
}
Because of the 0 as a false consider but you pass as a string then it will go the true.

Related

React Native:How to wait till a series of setState function to return before executing the next block of code?

setState in reactnative is asynchronous and I have a series of setState statements in my code and I want the code after these setState statements execute only after all the setState returns
Code
validate = () => {
this.changedNumber();
const reg = /^[0]?[789]\d{9}$/;
if (this.state.spaceName == null || this.state.spaceName =='') {
this.setState({
error_spaceName: "Name of space is required",
})
} else if (this.state.spaceName.length < 3) {
this.setState({
error_spaceName: "Name of space should be of minimum 3 character length",
})
}
else {
this.setState({
error_spaceName: null,
})
}
if (this.state.code === null || this.state.code === '') {
this.setState({
error_phone: "Phone Number is required",
})
} else if (isValidNumber(Number(this.state.code)) === false) {
this.setState({
error_phone: "Contact number should be a Kuwait number",
})
}
else {
this.setState({
error_phone: null,
})
}
if (this.state.error == null && this.state.error_spaceName == null && this.state.error_phone == null) {
this.props.navigation.navigate("LocationScreen")
}
}
What happnes here is that
if (this.state.error == null && this.state.error_spaceName == null && this.state.error_phone == null) {
this.props.navigation.navigate("LocationScreen")
}
this part of code gets executed before all the setState returns .I want to wait till all the setStates returns before checking the conditions? What's the proper way to acheieve this?
You are't able to use was updated state after setState in one block , so because you use class components , you are able to use componentDidUpdate for solving it :
//...
componentDidUpdate(prevProps, prevState){
if (prevState.error != this.state.error
|| prevState.error_spaceName != this.state.error_spaceName
|| prevState.error_phone != this.state.error_phone){
if (this.state.error == null && this.state.error_spaceName == null && this.state.error_phone == null) {
this.props.navigation.navigate("LocationScreen")
}
}
}
//...

Manipulating props using default in vuejs

Basically, I have very less edge cases where I need to change the value of props on init like so,
props : {
columnName : String,
setValue: {
validator: function (value) {
//enum edge cases
let _value = value;
if(value === 'YES' || value === 'ACTIVE'){
value = 0;
}
else if(value === 'NO' || value === 'VOID'){
value = 1;
}
console.log(_value);
return _value;
}
}
},
Is this possible, I did try this but it is still sending the actual values instead of 0/1.
You could try to return 'value' rather than '_value'.
However, I believe this is a job for a computed property, rather than trying to manipulate the prop directly.
computed:{
computedSetValue(){
if(this.setValue === 'YES' || this.setValue === 'ACTIVE'){
return 0
}
else if(this.setValue=== 'NO' || this.setValue=== 'VOID'){
return 1
}
return 0
}
}
Then, you may use this.computedSetValue as you do this.setValue

Vuejs check for a null or undefined value in a method

I don't understand why I can't do
openAndFillModalSoin(soin)
{
this.show = true,
this.vDate = soin.date,
this.vCategorie = soin.categoriesoin.name,
//This can be null
if(soin.rabaisraion){
this.vReasonReduction = soin.rabaisraison.id;
}
this.vPaiement = soin.moyendepaiement.nam,
this.vRefer = soin.referedBy,
//This can be null aswell
this.vGiftCard = soin.boncadeau.id,
this.vVoucher = soin.bonreduction.id;
this.vID = soin.id;
},
The "if" parts doesn't work, it asks for an expression.
You have commas instead of semicolons ending the preceding line.
if(soin.rabaisraion){
this.vReasonReduction = soin.rabaisraison.id;
}
This this code will run when the following is NOT TRUE
soin.rabaisraion is the number 0, false, null, undefined, or an empty string.
To reiterate, the string 'false', the string '0' and and an array (empty or not) are all true.
Also, if soin is null or undefined, that will be a runtime error.
Perhaps you want this:
if(soin && soin.rabaisraion){
this.vReasonReduction = soin.rabaisraison.id;
}
Regardless, add a log before to see what's going on:
console.log('checking soin', soin)
console.log('checking boolean soin', !!soin)
if(soin && soin.rabaisraion){
this.vReasonReduction = soin.rabaisraison.id;
}
The '!!' will force the value to boolean.
//check undefined Array
if (typeof myArray === "undefined") {
alert("myArray is undefined");
}
// check undefined object
if (typeof myObj === "undefined") {
alert("myObj is undefined");
}
//check object property
if (typeof myObj.some_property === "undefined") {
alert("some_property is undefined");
}

Validating a non-empty String in Lo-Dash [duplicate]

Is there a string.Empty in JavaScript, or is it just a case of checking for ""?
Empty string, undefined, null, ...
To check for a truthy value:
if (strValue) {
// strValue was non-empty string, true, 42, Infinity, [], ...
}
To check for a falsy value:
if (!strValue) {
// strValue was empty string, false, 0, null, undefined, ...
}
Empty string (only!)
To check for exactly an empty string, compare for strict equality against "" using the === operator:
if (strValue === "") {
// strValue was empty string
}
To check for not an empty string strictly, use the !== operator:
if (strValue !== "") {
// strValue was not an empty string
}
For checking if a variable is falsey or if it has length attribute equal to zero (which for a string, means it is empty), I use:
function isEmpty(str) {
return (!str || str.length === 0 );
}
(Note that strings aren't the only variables with a length attribute, arrays have them as well, for example.)
Alternativaly, you can use the (not so) newly optional chaining and arrow functions to simplify:
const isEmpty = (str) => (!str?.length);
It will check the length, returning undefined in case of a nullish value, without throwing an error. In the case of an empty value, zero is falsy and the result is still valid.
For checking if a variable is falsey or if the string only contains whitespace or is empty, I use:
function isBlank(str) {
return (!str || /^\s*$/.test(str));
}
If you want, you can monkey-patch the String prototype like this:
String.prototype.isEmpty = function() {
// This doesn't work the same way as the isEmpty function used
// in the first example, it will return true for strings containing only whitespace
return (this.length === 0 || !this.trim());
};
console.log("example".isEmpty());
Note that monkey-patching built-in types are controversial, as it can break code that depends on the existing structure of built-in types, for whatever reason.
All the previous answers are good, but this will be even better. Use dual NOT operators (!!):
if (!!str) {
// Some code here
}
Or use type casting:
if (Boolean(str)) {
// Code here
}
Both do the same function. Typecast the variable to Boolean, where str is a variable.
It returns false for null, undefined, 0, 000, "", false.
It returns true for all string values other than the empty string (including strings like "0" and " ")
The closest thing you can get to str.Empty (with the precondition that str is a String) is:
if (!str.length) { ...
If you need to make sure that the string is not just a bunch of empty spaces (I'm assuming this is for form validation) you need to do a replace on the spaces.
if(str.replace(/\s/g,"") == ""){
}
I use:
function empty(e) {
switch (e) {
case "":
case 0:
case "0":
case null:
case false:
case undefined:
return true;
default:
return false;
}
}
empty(null) // true
empty(0) // true
empty(7) // false
empty("") // true
empty((function() {
return ""
})) // false
Performance
I perform tests on macOS v10.13.6 (High Sierra) for 18 chosen solutions. Solutions works slightly different (for corner-case input data) which was presented in the snippet below.
Conclusions
the simple solutions based on !str,==,=== and length are fast for all browsers (A,B,C,G,I,J)
the solutions based on the regular expression (test,replace) and charAt are slowest for all browsers (H,L,M,P)
the solutions marked as fastest was fastest only for one test run - but in many runs it changes inside 'fast' solutions group
Details
In the below snippet I compare results of chosen 18 methods by use different input parameters
"" "a" " "- empty string, string with letter and string with space
[] {} f- array, object and function
0 1 NaN Infinity - numbers
true false - Boolean
null undefined
Not all tested methods support all input cases.
function A(str) {
let r=1;
if (!str)
r=0;
return r;
}
function B(str) {
let r=1;
if (str == "")
r=0;
return r;
}
function C(str) {
let r=1;
if (str === "")
r=0;
return r;
}
function D(str) {
let r=1;
if(!str || 0 === str.length)
r=0;
return r;
}
function E(str) {
let r=1;
if(!str || /^\s*$/.test(str))
r=0;
return r;
}
function F(str) {
let r=1;
if(!Boolean(str))
r=0;
return r;
}
function G(str) {
let r=1;
if(! ((typeof str != 'undefined') && str) )
r=0;
return r;
}
function H(str) {
let r=1;
if(!/\S/.test(str))
r=0;
return r;
}
function I(str) {
let r=1;
if (!str.length)
r=0;
return r;
}
function J(str) {
let r=1;
if(str.length <= 0)
r=0;
return r;
}
function K(str) {
let r=1;
if(str.length === 0 || !str.trim())
r=0;
return r;
}
function L(str) {
let r=1;
if ( str.replace(/\s/g,"") == "")
r=0;
return r;
}
function M(str) {
let r=1;
if((/^\s*$/).test(str))
r=0;
return r;
}
function N(str) {
let r=1;
if(!str || !str.trim().length)
r=0;
return r;
}
function O(str) {
let r=1;
if(!str || !str.trim())
r=0;
return r;
}
function P(str) {
let r=1;
if(!str.charAt(0))
r=0;
return r;
}
function Q(str) {
let r=1;
if(!str || (str.trim()==''))
r=0;
return r;
}
function R(str) {
let r=1;
if (typeof str == 'undefined' ||
!str ||
str.length === 0 ||
str === "" ||
!/[^\s]/.test(str) ||
/^\s*$/.test(str) ||
str.replace(/\s/g,"") === "")
r=0;
return r;
}
// --- TEST ---
console.log( ' "" "a" " " [] {} 0 1 NaN Infinity f true false null undefined ');
let log1 = (s,f)=> console.log(`${s}: ${f("")} ${f("a")} ${f(" ")} ${f([])} ${f({})} ${f(0)} ${f(1)} ${f(NaN)} ${f(Infinity)} ${f(f)} ${f(true)} ${f(false)} ${f(null)} ${f(undefined)}`);
let log2 = (s,f)=> console.log(`${s}: ${f("")} ${f("a")} ${f(" ")} ${f([])} ${f({})} ${f(0)} ${f(1)} ${f(NaN)} ${f(Infinity)} ${f(f)} ${f(true)} ${f(false)}`);
let log3 = (s,f)=> console.log(`${s}: ${f("")} ${f("a")} ${f(" ")}`);
log1('A', A);
log1('B', B);
log1('C', C);
log1('D', D);
log1('E', E);
log1('F', F);
log1('G', G);
log1('H', H);
log2('I', I);
log2('J', J);
log3('K', K);
log3('L', L);
log3('M', M);
log3('N', N);
log3('O', O);
log3('P', P);
log3('Q', Q);
log3('R', R);
And then for all methods I perform speed test case str = "" for browsers Chrome v78.0.0, Safari v13.0.4, and Firefox v71.0.0 - you can run tests on your machine here
You can use lodash:
_.isEmpty(value).
It covers a lot of cases like {}, '', null, undefined, etc.
But it always returns true for Number type of JavaScript primitive data types like _.isEmpty(10) or _.isEmpty(Number.MAX_VALUE) both returns true.
Very generic "All-In-One" Function (not recommended though):
function is_empty(x)
{
return ( //don't put newline after return
(typeof x == 'undefined')
||
(x == null)
||
(x == false) //same as: !x
||
(x.length == 0)
||
(x == 0) // note this line, you might not need this.
||
(x == "")
||
(x.replace(/\s/g,"") == "")
||
(!/[^\s]/.test(x))
||
(/^\s*$/.test(x))
);
}
However, I don't recommend to use that, because your target variable should be of specific type (i.e. string, or numeric, or object?), so apply the checks that are relative to that variable.
var s; // undefined
var s = ""; // ""
s.length // 0
There's nothing representing an empty string in JavaScript. Do a check against either length (if you know that the var will always be a string) or against ""
Try:
if (str && str.trim().length) {
//...
}
I would not worry too much about the most efficient method. Use what is most clear to your intention. For me that's usually strVar == "".
As per the comment from Constantin, if strVar could some how end up containing an integer 0 value, then that would indeed be one of those intention-clarifying situations.
A lot of answers, and a lot of different possibilities!
Without a doubt for quick and simple implementation the winner is: if (!str.length) {...}
However, as many other examples are available. The best functional method to go about this, I would suggest:
function empty(str)
{
if (typeof str == 'undefined' || !str || str.length === 0 || str === "" || !/[^\s]/.test(str) || /^\s*$/.test(str) || str.replace(/\s/g,"") === "")
return true;
else
return false;
}
A bit excessive, I know.
check that var a; exist
trim out the false spaces in the value, then test for emptiness
if ((a)&&(a.trim()!=''))
{
// if variable a is not empty do this
}
You could also go with regular expressions:
if((/^\s*$/).test(str)) { }
Checks for strings that are either empty or filled with whitespace.
I usually use something like this,
if (!str.length) {
// Do something
}
Also, in case you consider a whitespace filled string as "empty".
You can test it with this regular expression:
!/\S/.test(string); // Returns true if blank.
If one needs to detect not only empty but also blank strings, I'll add to Goral's answer:
function isEmpty(s){
return !s.length;
}
function isBlank(s){
return isEmpty(s.trim());
}
if ((str?.trim()?.length || 0) > 0) {
// str must not be any of:
// undefined
// null
// ""
// " " or just whitespace
}
Or in function form:
const isNotNilOrWhitespace = input => (input?.trim()?.length || 0) > 0;
const isNilOrWhitespace = input => (input?.trim()?.length || 0) === 0;
Starting with:
return (!value || value == undefined || value == "" || value.length == 0);
Looking at the last condition, if value == "", its length must be 0. Therefore drop it:
return (!value || value == undefined || value == "");
But wait! In JavaScript, an empty string is false. Therefore, drop value == "":
return (!value || value == undefined);
And !undefined is true, so that check isn't needed. So we have:
return (!value);
And we don't need parentheses:
return !value
I use a combination, and the fastest checks are first.
function isBlank(pString) {
if (!pString) {
return true;
}
// Checks for a non-white space character
// which I think [citation needed] is faster
// than removing all the whitespace and checking
// against an empty string
return !/[^\s]+/.test(pString);
}
I have not noticed an answer that takes into account the possibility of null characters in a string. For example, if we have a null character string:
var y = "\0"; // an empty string, but has a null character
(y === "") // false, testing against an empty string does not work
(y.length === 0) // false
(y) // true, this is also not expected
(y.match(/^[\s]*$/)) // false, again not wanted
To test its nullness one could do something like this:
String.prototype.isNull = function(){
return Boolean(this.match(/^[\0]*$/));
}
...
"\0".isNull() // true
It works on a null string, and on an empty string and it is accessible for all strings. In addition, it could be expanded to contain other JavaScript empty or whitespace characters (i.e. nonbreaking space, byte order mark, line/paragraph separator, etc.).
Meanwhile we can have one function that checks for all 'empties' like null, undefined, '', ' ', {}, [].
So I just wrote this.
var isEmpty = function(data) {
if(typeof(data) === 'object'){
if(JSON.stringify(data) === '{}' || JSON.stringify(data) === '[]'){
return true;
}else if(!data){
return true;
}
return false;
}else if(typeof(data) === 'string'){
if(!data.trim()){
return true;
}
return false;
}else if(typeof(data) === 'undefined'){
return true;
}else{
return false;
}
}
Use cases and results.
console.log(isEmpty()); // true
console.log(isEmpty(null)); // true
console.log(isEmpty('')); // true
console.log(isEmpty(' ')); // true
console.log(isEmpty(undefined)); // true
console.log(isEmpty({})); // true
console.log(isEmpty([])); // true
console.log(isEmpty(0)); // false
console.log(isEmpty('Hey')); // false
I did some research on what happens if you pass a non-string and non-empty/null value to a tester function. As many know, (0 == "") is true in JavaScript, but since 0 is a value and not empty or null, you may want to test for it.
The following two functions return true only for undefined, null, empty/whitespace values and false for everything else, such as numbers, Boolean, objects, expressions, etc.
function IsNullOrEmpty(value)
{
return (value == null || value === "");
}
function IsNullOrWhiteSpace(value)
{
return (value == null || !/\S/.test(value));
}
More complicated examples exists, but these are simple and give consistent results. There is no need to test for undefined, since it's included in (value == null) check. You may also mimic C# behaviour by adding them to String like this:
String.IsNullOrEmpty = function (value) { ... }
You do not want to put it in Strings prototype, because if the instance of the String-class is null, it will error:
String.prototype.IsNullOrEmpty = function (value) { ... }
var myvar = null;
if (1 == 2) { myvar = "OK"; } // Could be set
myvar.IsNullOrEmpty(); // Throws error
I tested with the following value array. You can loop it through to test your functions if in doubt.
// Helper items
var MyClass = function (b) { this.a = "Hello World!"; this.b = b; };
MyClass.prototype.hello = function () { if (this.b == null) { alert(this.a); } else { alert(this.b); } };
var z;
var arr = [
// 0: Explanation for printing, 1: actual value
['undefined', undefined],
['(var) z', z],
['null', null],
['empty', ''],
['space', ' '],
['tab', '\t'],
['newline', '\n'],
['carriage return', '\r'],
['"\\r\\n"', '\r\n'],
['"\\n\\r"', '\n\r'],
['" \\t \\n "', ' \t \n '],
['" txt \\t test \\n"', ' txt \t test \n'],
['"txt"', "txt"],
['"undefined"', 'undefined'],
['"null"', 'null'],
['"0"', '0'],
['"1"', '1'],
['"1.5"', '1.5'],
['"1,5"', '1,5'], // Valid number in some locales, not in JavaScript
['comma', ','],
['dot', '.'],
['".5"', '.5'],
['0', 0],
['0.0', 0.0],
['1', 1],
['1.5', 1.5],
['NaN', NaN],
['/\S/', /\S/],
['true', true],
['false', false],
['function, returns true', function () { return true; } ],
['function, returns false', function () { return false; } ],
['function, returns null', function () { return null; } ],
['function, returns string', function () { return "test"; } ],
['function, returns undefined', function () { } ],
['MyClass', MyClass],
['new MyClass', new MyClass()],
['empty object', {}],
['non-empty object', { a: "a", match: "bogus", test: "bogus"}],
['object with toString: string', { a: "a", match: "bogus", test: "bogus", toString: function () { return "test"; } }],
['object with toString: null', { a: "a", match: "bogus", test: "bogus", toString: function () { return null; } }]
];
I didn't see a good answer here (at least not an answer that fits for me)
So I decided to answer myself:
value === undefined || value === null || value === "";
You need to start checking if it's undefined. Otherwise your method can explode, and then you can check if it equals null or is equal to an empty string.
You cannot have !! or only if(value) since if you check 0 it's going to give you a false answer (0 is false).
With that said, wrap it up in a method like:
public static isEmpty(value: any): boolean {
return value === undefined || value === null || value === "";
}
PS.: You don't need to check typeof, since it would explode and throw even before it enters the method
Trimming whitespace with the null-coalescing operator:
if (!str?.trim()) {
// do something...
}
There is a lot of useful information here, but in my opinion, one of the most important elements was not addressed.
null, undefined, and "" are all falsy.
When evaluating for an empty string, it's often because you need to replace it with something else.
In which case, you can expect the following behavior.
var a = ""
var b = null
var c = undefined
console.log(a || "falsy string provided") // prints ->"falsy string provided"
console.log(b || "falsy string provided") // prints ->"falsy string provided"
console.log(c || "falsy string provided") // prints ->"falsy string provided"
With that in mind, a method or function that can return whether or not a string is "", null, or undefined (an invalid string) versus a valid string is as simple as this:
const validStr = (str) => str ? true : false
validStr(undefined) // returns false
validStr(null) // returns false
validStr("") // returns false
validStr("My String") // returns true
Try this:
export const isEmpty = string => (!string || !string.length);
All these answers are nice.
But I cannot be sure that variable is a string, doesn't contain only spaces (this is important for me), and can contain '0' (string).
My version:
function empty(str){
return !str || !/[^\s]+/.test(str);
}
empty(null); // true
empty(0); // true
empty(7); // false
empty(""); // true
empty("0"); // false
empty(" "); // true
Sample on jsfiddle.
There's no isEmpty() method, you have to check for the type and the length:
if (typeof test === 'string' && test.length === 0){
...
The type check is needed in order to avoid runtime errors when test is undefined or null.

Is there a consistent way to test for undefined and null in typescript 2.0? [duplicate]

Since TypeScript is strongly-typed, simply using if () {} to check for null and undefined doesn't sound right.
Does TypeScript have any dedicated function or syntax sugar for this?
Using a juggling-check, you can test both null and undefined in one hit:
if (x == null) {
If you use a strict-check, it will only be true for values set to null and won't evaluate as true for undefined variables:
if (x === null) {
You can try this with various values using this example:
var a: number;
var b: number = null;
function check(x, name) {
if (x == null) {
console.log(name + ' == null');
}
if (x === null) {
console.log(name + ' === null');
}
if (typeof x === 'undefined') {
console.log(name + ' is undefined');
}
}
check(a, 'a');
check(b, 'b');
Output
"a == null"
"a is undefined"
"b == null"
"b === null"
if( value ) {
}
will evaluate to true if value is not:
null
undefined
NaN
empty string ''
0
false
typescript includes javascript rules.
In TypeScript 3.7 we have now Optional chaining and Nullish Coalescing to check null and undefined in the same time, example:
let x = foo?.bar.baz();
this code will check if foo is defined otherwise it will return undefined
old way :
if(foo != null && foo != undefined) {
x = foo.bar.baz();
}
this:
let x = (foo === null || foo === undefined) ? undefined : foo.bar();
if (foo && foo.bar && foo.bar.baz) { // ... }
With optional chaining will be:
let x = foo?.bar();
if (foo?.bar?.baz) { // ... }
another new feature is Nullish Coalescing, example:
let x = foo ?? bar(); // return foo if it's not null or undefined otherwise calculate bar
old way:
let x = (foo !== null && foo !== undefined) ?
foo :
bar();
BONUS
Does TypeScript has dedicated function or syntax sugar for this
TypeScript fully understands the JavaScript version which is something == null.
TypeScript will correctly rule out both null and undefined with such checks.
More
https://basarat.gitbook.io/typescript/recap/null-undefined
I did different tests on the typescript playground:
http://www.typescriptlang.org/play/
let a;
let b = null;
let c = "";
var output = "";
if (a == null) output += "a is null or undefined\n";
if (b == null) output += "b is null or undefined\n";
if (c == null) output += "c is null or undefined\n";
if (a != null) output += "a is defined\n";
if (b != null) output += "b is defined\n";
if (c != null) output += "c is defined\n";
if (a) output += "a is defined (2nd method)\n";
if (b) output += "b is defined (2nd method)\n";
if (c) output += "c is defined (2nd method)\n";
console.log(output);
gives:
a is null or undefined
b is null or undefined
c is defined
so:
checking if (a == null) is right to know if a is null or undefined
checking if (a != null) is right to know if a is defined
checking if (a) is wrong to know if a is defined
You may want to try
if(!!someValue)
with !!.
Explanation
The first ! will turn your expression into a boolean value.
Then !someValue is true if someValue is falsy and false if someValue is truthy. This might be confusing.
By adding another !, the expression is now true if someValue is truthy and false if someValue is falsy, which is much easier to manage.
Discussion
Now, why do I bother myself with if (!!someValue) when something like if (someValue) would have give me the same result?
Because !!someValue is precisely a boolean expression, whereas someValue could be absolutely anything. This kind of expression will now alow to write functions (and God we need those) like:
isSomeValueDefined(): boolean {
return !!someValue
}
instead of:
isSomeValueDefined(): boolean {
if(someValue) {
return true
}
return false
}
I hope it helps.
For Typescript 2.x.x you should do it in a following way(using type guard):
tl;dr
function isDefined<T>(value: T | undefined | null): value is T {
return <T>value !== undefined && <T>value !== null;
}
Why?
In this way isDefined() will respect variable's type and the following code would know take this check in account.
Example 1 - basic check:
function getFoo(foo: string): void {
//
}
function getBar(bar: string| undefined) {
getFoo(bar); //ERROR: "bar" can be undefined
if (isDefined(bar)) {
getFoo(bar); // Ok now, typescript knows that "bar' is defined
}
}
Example 2 - types respect:
function getFoo(foo: string): void {
//
}
function getBar(bar: number | undefined) {
getFoo(bar); // ERROR: "number | undefined" is not assignable to "string"
if (isDefined(bar)) {
getFoo(bar); // ERROR: "number" is not assignable to "string", but it's ok - we know it's number
}
}
I think this answer needs an update, check the edit history for the old answer.
Basically, you have three deferent cases null, undefined, and undeclared, see the snippet below.
// bad-file.ts
console.log(message)
You'll get an error says that variable message is undefined (aka undeclared), of course, the Typescript compiler shouldn't let you do that but REALLY nothing can prevent you.
// evil-file.ts
// #ts-gnore
console.log(message)
The compiler will be happy to just compile the code above.
So, if you're sure that all variables are declared you can simply do that
if ( message != null ) {
// do something with the message
}
the code above will check for null and undefined, BUT in case the message variable may be undeclared (for safety), you may consider the following code
if ( typeof(message) !== 'undefined' && message !== null ) {
// message variable is more than safe to be used.
}
Note: the order here typeof(message) !== 'undefined' && message !== null is very important you have to check for the undefined state first atherwise it will be just the same as message != null, thanks #Jaider.
SIMPLE ANSWER
Although Typescript is a strongly typed language, it has the same problems with pointers and variables initialization inherited from Javascript.
Javascript doesn't check whether a variable exists in the context, the so common undefined status.
to evaluate if value ISN'T null,undefined,0,false,"", or NaN:
if ( value )
or
if ( !!value )
for negative conditional, check if the value is null,undefined,0,false,"",or NaN:
if ( !value )
to test if is null or undefined:
if ( value == null )
to test only null:
if ( value === null )
to test only undefined:
if ( value === undefined )
MORE DETAILED ANSWER
1- It will evaluate to true if value is not: null, undefined, NaN, empty string '', 0, false
If the value is null,undefined,NaN,empty string,0, or false, will go to the else condition.
if ( value ) {
console.log('value is something different from 0, "", false, NaN, null, undefined');
} else {
console.log('value is 0, "", false, NaN, null or undefined');
}
if ( !!value ) {
console.log('value is something different from 0, "", false, NaN, null, undefined');
} else {
console.log('value is 0, "", false, NaN, null or undefined');
}
2- If you want a negative condition, then you'll need to use:
if ( !value ) {
console.log('value is 0, "", false, NaN, null or undefined');
} else {
console.log('value is something different from 0, "", false, NaN, null, undefined');
}
3- It will evaluate if value is null or undefined
if ( value == null ) {
console.log('is null or undefined');
} else {
console.log('it isnt null neither undefined');
}
4- Using a test with boolean values doesn't work.
It will NOT evaluate to true neither to false if value is null, undefined, 0, empty string, NaN
Both conditions will always go to the else condition.
With the exception if value is a boolean variable.
if ( value==true ) {
} else {
}
if ( value==false ) {
} else {
}
if(data){}
it's mean !data
null
undefined
false
....
If you want to pass tslint without setting strict-boolean-expressions to allow-null-union or allow-undefined-union, you need to use isNullOrUndefined from node's util module or roll your own:
// tslint:disable:no-null-keyword
export const isNullOrUndefined =
<T>(obj: T | null | undefined): obj is null | undefined => {
return typeof obj === "undefined" || obj === null;
};
// tslint:enable:no-null-keyword
Not exactly syntactic sugar but useful when your tslint rules are strict.
UPDATE (Sept 4, 2020)
You can now use the ?? operator to validate null and undefined "values" and set a default value. For example:
const foo = null;
const bar = foo ?? 'exampleValue';
console.log(bar); // This will print 'exampleValue' due to the value condition of the foo constant, in this case, a null value
As a verbose way, if you want to compare null and undefined values ONLY, use the following example code for reference:
const incomingValue : string = undefined;
const somethingToCompare : string = incomingValue; // If the line above is not declared, TypeScript will return an excepion
if (somethingToCompare == (undefined || null)) {
console.log(`Incoming value is: ${somethingToCompare}`);
}
If incomingValue is not declared, TypeScript should return an exception. If this is declared but not defined, the console.log() will return "Incoming value is: undefined". Note we are not using the strict equals operator.
The "correct" way (check the other answers for details), if the incomingValue is not a boolean type, just evaluate if its value is true, this will be evaluated according to the constant/variable type. A true string have to be defined explicitly as string using the = '' assignation. If not, it will be evaluated as false. Let's check this case using the same context:
const incomingValue : string = undefined;
const somethingToCompare0 : string = 'Trumpet';
const somethingToCompare1 : string = incomingValue;
if (somethingToCompare0) {
console.log(`somethingToCompare0 is: ${somethingToCompare0}`); // Will return "somethingToCompare0 is: Trumpet"
}
// Now, we will evaluate the second constant
if (somethingToCompare1) {
console.log(`somethingToCompare1 is: ${somethingToCompare1}`); // Launched if incomingValue is defined
} else {
console.log(`somethingToCompare1 is: ${somethingToCompare1}`); // Launched if incomingValue is undefined. Will return "somethingToCompare1 is: undefined"
}
If you are using TypeScript, it is a better approach to let the compiler check for nulls and undefineds (or the possibility thereof), rather than checking for them at run-time. (If you do want to check at run-time, then as many answers indicate, just use value == null).
Use the compile option strictNullChecks to tell the compiler to choke on possible null or undefined values. If you set this option, and then there is a situation where you do want to allow null and undefined, you can define the type as Type | null | undefined.
The simplest way is to use:
import { isNullOrUndefined } from 'util';
and than:
if (!isNullOrUndefined(foo))
We use a helper hasValue that both checks for nulls/undefined and ensures via TypeScript that unnecessary checks are not performed. (The latter is similar to how TS would complain about if ("a" === undefined), since it is always false).
Using this consistently is always safe, unlike !val which matches empty strings, zero, etc. It also avoid the use of fuzzy == matching which is almost always a bad practice - no need to introduce an exception.
type NullPart<T> = T & (null | undefined);
// Ensures unnecessary checks aren't performed - only a valid call if
// value could be nullable *and* could be non-nullable
type MustBeAmbiguouslyNullable<T> = NullPart<T> extends never
? never
: NonNullable<T> extends never
? never
: T;
export function hasValue<T>(
value: MustBeAmbiguouslyNullable<T>,
): value is NonNullable<MustBeAmbiguouslyNullable<T>> {
return (value as unknown) !== undefined && (value as unknown) !== null;
}
export function hasValueFn<T, A>(
value: MustBeAmbiguouslyNullable<T>,
thenFn: (value: NonNullable<T>) => A,
): A | undefined {
// Undefined matches .? syntax result
return hasValue(value) ? thenFn(value) : undefined;
}
Late to join this thread but I find this JavaScript hack very handy in checking whether a value is undefined
if(typeof(something) === 'undefined'){
// Yes this is undefined
}
May be to late! but you can use ?? operator in typescript.
see https://mariusschulz.com/blog/nullish-coalescing-the-operator-in-typescript
You can do this easily with a ternary operator and the new nullish coalesce operator.
First: check to see if it is true using the ternary. If so return false so the if statement does not run.
Second: because you now know the value is falsey, you can use the nullish coalesce operator to return true if it is nullish. Since it will return itself for any other value, if it is not nullish it will fail the if statement correctly.
let x = true;
console.log("starting tests")
if (x?false:x ?? true){
console.log(x,"is nullish")
}
x = false
if (x?false:x ?? true){
console.log(x,"is nullish")
}
x = 0;
if (x?false:x ?? true){
console.log(x,"is nullish")
}
x=1;
if (x?false:x ?? true){
console.log(x,"is nullish")
}
x="";
if (x?false:x ?? true){
console.log(x,"is nullish")
}
x="hello world";
if (x?false:x ?? true){
console.log(x,"is nullish")
}
x=null;
if (x?false:x ?? true){
console.log(x,"is nullish")
}
x=undefined;
if (x?false:x ?? true){
console.log(x,"is nullish")
}
you can use
if(x === undefined)
All,
The answer with the most votes, does not really work if you are working with an object. In that case, if a property is not present, the check will not work. And that was the issue in our case: see this sample:
var x =
{ name: "Homer", LastName: "Simpson" };
var y =
{ name: "Marge"} ;
var z =
{ name: "Bart" , LastName: undefined} ;
var a =
{ name: "Lisa" , LastName: ""} ;
var hasLastNameX = x.LastName != null;
var hasLastNameY = y.LastName != null;
var hasLastNameZ = z.LastName != null;
var hasLastNameA = a.LastName != null;
alert (hasLastNameX + ' ' + hasLastNameY + ' ' + hasLastNameZ + ' ' + hasLastNameA);
var hasLastNameXX = x.LastName !== null;
var hasLastNameYY = y.LastName !== null;
var hasLastNameZZ = z.LastName !== null;
var hasLastNameAA = a.LastName !== null;
alert (hasLastNameXX + ' ' + hasLastNameYY + ' ' + hasLastNameZZ + ' ' + hasLastNameAA);
Outcome:
true , false, false , true (in case of !=)
true , true, true, true (in case of !==) => so in this sample not the correct answer
plunkr link: https://plnkr.co/edit/BJpVHD95FhKlpHp1skUE
Since TypeScript is a typed superset of ES6 JavaScript. And lodash are a library of javascript.
Using lodash to checks if value is null or undefined can be done using _.isNil().
_.isNil(value)
Arguments
value (*): The value to check.
Returns
(boolean): Returns true if value is nullish, else false.
Example
_.isNil(null);
// => true
_.isNil(void 0);
// => true
_.isNil(NaN);
// => false
Link
Lodash Docs
A faster and shorter notation for null checks can be:
value == null ? "UNDEFINED" : value
This line is equivalent to:
if(value == null) {
console.log("UNDEFINED")
} else {
console.log(value)
}
Especially when you have a lot of null check it is a nice short notation.
I had this issue and some of the answer work just fine for JS but not for TS here is the reason.
//JS
let couldBeNullOrUndefined;
if(couldBeNullOrUndefined == null) {
console.log('null OR undefined', couldBeNullOrUndefined);
} else {
console.log('Has some value', couldBeNullOrUndefined);
}
That is all good as JS has no Types
//TS
let couldBeNullOrUndefined?: string | null; // THIS NEEDS TO BE TYPED AS undefined || null || Type(string)
if(couldBeNullOrUndefined === null) { // TS should always use strict-check
console.log('null OR undefined', couldBeNullOrUndefined);
} else {
console.log('Has some value', couldBeNullOrUndefined);
}
In TS if the variable wasn't defined with null when you try to check for that null the tslint | compiler will complain.
//tslint.json
...
"triple-equals":[true],
...
let couldBeNullOrUndefined?: string; // to fix it add | null
Types of property 'couldBeNullOrUndefined' are incompatible.
Type 'string | null' is not assignable to type 'string | undefined'.
Type 'null' is not assignable to type 'string | undefined'.
Usually I do the juggling-check as Fenton already discussed.
To make it more readable, you can use isNil from ramda.
import * as isNil from 'ramda/src/isNil';
totalAmount = isNil(totalAmount ) ? 0 : totalAmount ;
careful if you're using local storage, you can end up with the string undefined rather than the value undefined:
localStorage.setItem('mykey',JSON.stringify(undefined));
localStorage.getItem('mykey') === "undefined"
true
People may find this useful: https://github.com/angular/components/blob/master/src/cdk/coercion/boolean-property.spec.ts
/**
* #license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/** Coerces a data-bound value (typically a string) to a boolean. */
export function coerceBooleanProperty(value: any): boolean {
return value != null && `${value}` !== 'false';
}
import {coerceBooleanProperty} from './boolean-property';
describe('coerceBooleanProperty', () => {
it('should coerce undefined to false', () => {
expect(coerceBooleanProperty(undefined)).toBe(false);
});
it('should coerce null to false', () => {
expect(coerceBooleanProperty(null)).toBe(false);
});
it('should coerce the empty string to true', () => {
expect(coerceBooleanProperty('')).toBe(true);
});
it('should coerce zero to true', () => {
expect(coerceBooleanProperty(0)).toBe(true);
});
it('should coerce the string "false" to false', () => {
expect(coerceBooleanProperty('false')).toBe(false);
});
it('should coerce the boolean false to false', () => {
expect(coerceBooleanProperty(false)).toBe(false);
});
it('should coerce the boolean true to true', () => {
expect(coerceBooleanProperty(true)).toBe(true);
});
it('should coerce the string "true" to true', () => {
expect(coerceBooleanProperty('true')).toBe(true);
});
it('should coerce an arbitrary string to true', () => {
expect(coerceBooleanProperty('pink')).toBe(true);
});
it('should coerce an object to true', () => {
expect(coerceBooleanProperty({})).toBe(true);
});
it('should coerce an array to true', () => {
expect(coerceBooleanProperty([])).toBe(true);
});
});
You could use:
if (!!variable) {}
it equals writting
it (variable != null && variable != undefined) {}
I always write it like this:
var foo:string;
if(!foo){
foo="something";
}
This will work fine and I think it's very readable.