Casting a String to Boolean in Javascript - javascript

In Javascript, is there any difference between
if(!!isLoaded) and if(Boolean(isLoaded))?
I recently started working on an app where the previous developer did this a lot.
I ran a few tests and they both seem to convert strings "true" and "false" to the Boolean type, which I'm assuming is the main reason for doing this.
If they are indeed the same, what is everyone's opinion on which one is more readable?

Both if (!!isLoaded) and if (Boolean(isLoaded)) will be equivalent to if (isLoaded), as JavaScript only looks for truthy values for if conditions. If you need the specific strings "true" and "false", you'll need to compare to that directly with if (isLoaded === "true").

I personally feel the !! is easier to read. They both convert to boolean though.
However like jaromeda mentioned neither will work for this situation. Both string "true" and "false" result in true since values exist.

Empty String is already treated as negative condition in JS, Indeed,...
The following are treated as negative condition in JS :
0 👉🏼 const v = 0 ; (!v) && doSomething()
Empty string 👉🏼 const v = '' ; (!v) && doSomething() ⬅ ⚠️ Attention please since your question is about casting String to Boolean.
false 👉🏼 const v = false ; (!v) && doSomething()
null 👉🏼 const v = null ; (!v) && doSomething()
undefined 👉🏼 const v = undefined ; (!v) && doSomething()
And those 5 values are equals using == and not equal using ===.
Otherwise , v is treated as positive condition.
let zero = 0 ;
let falseVar = false;
console.log(` zero == falseVar ? `, zero == falseVar);
console.log(` zero === falseVar ? `, zero === falseVar);
let emptyString= ''
console.log(` zero == emptyString ? `, zero == emptyString);
console.log(` zero === emptyString ? `, zero === emptyString);

Related

Check if String can be converted to number

I created the following Typescript extension to convert a string to Number:
declare global {
interface String {
toNumber(): number | null;
}
}
String.prototype.toNumber = function(this: string) {
return parseFloat(this);
}
When it is not possible to parse the string to number either because it is invalid, null, undefined, etc I would always like to return null.
How can I do this?
I am assuming you already understand the differences between parseFloat / Number as conversion mechanisms.
Effectively all you need to do is check if the output is NaN. You can do this by:
String.prototype.toNumber = function(this: string) {
const num = parseFloat(this);
return Number.isNaN(num) ? null : num;
}
If you want to return either a non-zero valid number (well, note that NaN is a number, but I think I know what you mean), then check for what you don't want before returning:
Object.defineProperty(String.prototype, "toNumber", {
value: function(str) {
let num = Number(str);
return num === 0 || isNaN(num) ? null : num;
}
});
(Defining properties directly on the prototype is a bad habit and can lead to weird behavior; using .defineProperty gives you a property that is not enumerable.)
Oh, and that's JavaScript, obviously, not Typescript.
A simple answer would be to use return Number(this) || null;
The Number function will convert to a number or NaN, NaN || null will return null (because NaN is falsey).
Updated added testing for zero condition, which with the above code would have also returned null. If that is not what you want, this code will allow zero to return. (Note that this can be done many different ways!):
const parsedValue = Number(this);
return parsedValue === 0 ? parsedValue : parsedValue || null;
Updated to use the parseFloat function, example of early exit for string of '0'. Very similar to the previous updated example.
if (this === '0') {
return 0;
}
return parseFloat(this) || null;

Checking and converting some value to number using conditional operator

Given a string stored in a variable 'givenValue'. If it's all numbers, convert the string to number
(e.g. '11' to 11, 'a1' to 'a1')
and assign it to a variable 'value':
const value = givenValue - 0 === NaN ? givenValue : givenValue - 0;
But the output is not what I expected:
const givenValue = 'a1';
console.log(value); // NaN
const givenValue = '1';
console.log(value); // 1
Seems like the value of 'givenValue' is reassigned at the time of the 'if' condition being checked, or the condition check is not working.
You can use isNaN function to check something is NaN or not:
const givenValue = 'a1';
console.log(isNaN(givenValue) ? givenValue : +givenValue);
Also, if you want to check something is numeric or not before casting to a number, you can use isNaN function with isFinite function:
const givenValue = 'a1';
const value = !isNaN(parseFloat(givenValue)) && isFinite(givenValue)
? givenValue : +givenValue;
console.log(value);
Strings that aren't fully numbers but have numeric characters may well return a number other than NaN in many circumstances - see that link for a full description of how the algorithm works. Suffice to say, it's slightly complicated, and isn't what you're looking for. (eg, you'd want '123e456' to fail, but that'd actually give you Infinity instead. Whitespace will be permitted too.) (Also, a === NaN check will always return false, because NaN isn't equal to anything)
Instead, use a regular expression to check that the string contains only digits:
const value = /^\d+$/.test(givenValue) ? Number(givenValue) : givenValue;
If you want to include possible decimal amounts too, then add an optional group of . followed by digits:
const value = /^\d+(?:\.\d+)?$/.test(givenValue) ? Number(givenValue) : givenValue;
// ^^^^^^^^^^
NaN doesn't equal itself. Try like this: givenValue - 0 !== givenValue - 0 ? givenValue : givenValue - 0.
In Javascript, NaN === NaN is alway false.
So you should use isNaN(givenValue - 0) rather than givenValue - 0 === NaN
console.log(NaN === NaN) // false
console.log(NaN == NaN) // false
console.log(isNaN(NaN)) // true
const fixedFunc = (givenValue) => isNaN(givenValue - 0) ? givenValue : givenValue - 0;
console.log(JSON.stringify({
"fixedFunc('a1')": fixedFunc('a1'),
"fixedFunc('1')": fixedFunc('1')
}))
ONLY WORKS WITH NONZERO NUMBERS
A simpler method would be to use const value = givenValue - 0 || givenValue;
var givenValue = '1';
var value = givenValue - 0 || givenValue;
console.log(value);
givenValue = 'a1';
value = givenValue - 0 || givenValue;
console.log(value);

convert number to string returns empty if number 0

Trying to convert string to a number, works fine apart from when the number is zero it returns an empty string;
I understand 0 is false, but I just need a neat way of it returning the string "0"
I'm using:
const num = this.str ? this.str.toString() : '' ;
I even thought of using es6 and simply ${this.str} but that didn't work
Because 0 is "false-y" in JavaScript, as you've already figured out, you can't utilized it in a conditional. Instead, ask yourself what the conditional is really trying to solve.
Are you worried about null / undefined values? Perhaps this is better:
const num = (typeof this.str !== "undefined" && this.str !== null) ? this.str.toString() : "";
Odds are you really only care if this.str is a Number, and in all other cases want to ignore it. What if this.str is a Date, or an Array? Both Date and Array have a .toString() method, which means you may have some weird bugs crop up if one slips into your function unexpectedly.
So a better solution may be:
const num = (typeof this.str === "number") ? this.str.toString() : "";
You can also put your code in a try catch block
const num = ''
try {
num = this.str.toString();
} catch(e) {
// Do something here if you want.
}
Just adding to given answers - if you do:
x >> 0
you will convert anything to a Number
'7' >> 0 // 7
'' >> 0 // 0
true >> 0 // 1
[7] >> 0 // 7
It's a right shift bit operation. You can do magic with this in many real life cases, like described in this article.
In my case, the zero (number) that I wanted to converted to a string (which was the value of an option in a select element) was a value in an enum.
So I did this, since the enum was generated by another process and I could not change it:
let stringValue = '';
if (this.input.enumValue === 0) {
stringValue = '0';
} else {
stringValue = this.input.enumValue.toString();
}

Typescript : check a string for number

I'm new to web development, and in my function want to check if a given string value is a number. In case the string isn't a valid number I want to return null.
The following works for all cases except when the string is "0" in which case it returns null.
parseInt(columnSortSettings[0]) || null;
How do I prevent this from happening. Apparantly parseInt doesn't consider 0 as an integer!
Since 0 is act as false , so you can use isNaN() in this case
var res = parseInt(columnSortSettings[0], 10);
return isNaN(res) ? null : res;
It's because you are basically testing 0 which is also false.
You can do
var n = columnSortSettings[0];
if(parseInt(n, 10) || n === '0'){
//...
}
You can also test instead if it's a number
if(typeof(parseInt(n, 10)) === 'number'){
//...
}
But beware cause
typeof Infinity === 'number';
typeof NaN === 'number';
You can use the isNumeric operator from rxjs library (importing rxjs/util/isNumeric

What causes isNaN to malfunction? [duplicate]

This question already has answers here:
Validate decimal numbers in JavaScript - IsNumeric()
(52 answers)
Closed 9 years ago.
I'm simply trying to evaluate if an input is a number, and figured isNaN would be the best way to go. However, this causes unreliable results. For instance, using the following method:
function isNumerical(value) {
var isNum = !isNaN(value);
return isNum ? "<mark>numerical</mark>" : "not numerical";
}
on these values:
isNumerical(123)); // => numerical
isNumerical("123")); // => numerical
isNumerical(null)); // => numerical
isNumerical(false)); // => numerical
isNumerical(true)); // => numerical
isNumerical()); // => not numerical
shown in this fiddle: http://jsfiddle.net/4nm7r/1
Why doesn't isNaN always work for me?
isNaN returns true if the value passed is not a number(NaN)(or if it cannot be converted to a number, so, null, true and false will be converted to 0), otherwise it returns false. In your case, you have to remove the ! before the function call!
It is very easy to understand the behaviour of your script. isNaN simply checks if a value can be converted to an int. To do this, you have just to multiply or divide it by 1, or subtract or add 0. In your case, if you do, inside your function, alert(value * 1); you will see that all those passed values will be replaced by a number(0, 1, 123) except for undefined, whose numerical value is NaN.
You can't compare any value to NaN because it will never return false(even NaN === NaN), I think that's because NaN is dynamically generated... But I'm not sure.
Anyway you can fix your code by simply doing this:
function isNumerical(value) {
var isNum = !isNaN(value / 1); //this will force the conversion to NaN or a number
return isNum ? "<mark>numerical</mark>" : "not numerical";
}
Your ternary statement is backward, if !isNaN() returns true you want to say "numerical"
return isNum ? "not numerical" : "<mark>numerical</mark>";
should be:
return isNum ? "<mark>numerical</mark>" : "not numerical";
See updated fiddle:
http://jsfiddle.net/4nm7r/1/
Now that you already fixed the reversed logic pointed out on other answers, use parseFloat to get rid of the false positives for true, false and null:
var isNum = !isNaN(parseFloat(value));
Just keep in mind the following kinds of outputs from parseFloat:
parseFloat("200$"); // 200
parseFloat("200,100"); // 200
parseFloat("200 foo"); // 200
parseFloat("$200"); // NaN
(i.e, if the string starts with a number, parseFloat will extract the first numeric part it can find)
I suggest you use additional checks:
function isNumerical(value) {
var isNum = !isNaN(value) && value !== null && value !== undefined;
return isNum ? "<mark>numerical</mark>" : "not numerical";
}
If you would like treat strings like 123 like not numerical than you should add one more check:
var isNum = !isNaN(value) && value !== null && value !== undefined && (typeof value === 'number');

Categories

Resources