Why is angular.isNumber() not working as expected? - javascript

It appears as if AngularJS's angular.isNumber is not working. It doesn't work with strings that are numbers. Am I doing something wrong? Should I just use isNaN()?
angular.isNumber('95.55') == false
angular.isNumber('95.55' * 1) == true
angular.isNumber('bla' * 1) == true
angular.isNumber(NaN) == true
I need something to see if a string is a number (when it actually is) and angular.isNumber() won't let me do that unless I multiply by 1, but if I do that then it will always be true. Also NaN is not a number (by definition) and so should return false.

In JavaScript, typeof NaN === 'number'.
If you need to recognise a String as a Number, cast it to Number, convert back to String and compare this against the input, for example.
function stringIsNumber(s) {
var x = +s; // made cast obvious for demonstration
return x.toString() === s;
}
stringIsNumber('95.55'); // true
stringIsNumber('foo'); // false
// still have
stringIsNumber('NaN'); // true

I was working on the same problem and I was trying to work around that edge case. So I created a slightly different approach.
FIDDLE
function isStringNumber(str) {
var parsed = parseFloat(str);
var casted = +str;
return parsed === casted && !isNaN(parsed) && !isNaN(casted);
}

Use it as below,
angular.isNumber(eval('99.55'))
for other expressions also we may use eval(input).
Note: eval() is a javascript method
Edit:
It is not recommended to use eval(), as document says Never use eval()!
Thanks #Diogo Kollross

Related

how many ways to check if x is integer and which one is most efficient?

I already checked what is the best way to check variable type in javascript
question on So but didn't found answer of my question.
In javascript how many ways to find if input type is integer? which one is efficient?
I was looking the way to find the integer in javascript and found number of ways to do this:
Using typeof
function isInteger(x)
{
return (typeof x === 'number') && (x % 1 === 0);
}
console.log(isInteger(10));
console.log(isInteger(10.1))
Using parseInt
function isInteger(x)
{
return parseInt(x, 10) === x;
}
console.log(isInteger(10));
console.log(isInteger(10.1));
Using Math.round
function isInteger(x)
{
return Math.round(x) === x;
}
console.log(isInteger(10));
console.log(isInteger(10.1));
Is there any other way to find the type of Integer and which one will be most efficient for consider small to large integer values.
The most intuitive one is Number.isInteger(), at least in my opinion
function isInteger(x)
{
return Number.isInteger(x);
}
console.log(isInteger(10)); // Output: True
console.log(isInteger(10.1)); // Output: False
Edit
As for efficiency, I created a benchmark on jsben.ch where I try all your methods and mine, you can see for yourself ;)
Link
I just tested the speed of each code at JSBEN.CH
typeof => 347 ms
parseInt => 338 ms
Math.round => 367 ms
Interestingly, parseInt is the fastest way!
It's only the speed comparison. Go with Number.isInteger(x) instead! It's the instinctive & fastest of all.
Your propositions seem fine, but let's add for completion the polyfill Mozilla puts forward :
Number.isInteger = Number.isInteger || function(value) {
return typeof value === 'number' &&
isFinite(value) &&
Math.floor(value) === value;
};
I am concluding answer for this question after some resarch
From ECMAscript 6 which introduces a new Number.isInteger() function for precisely this purpose.
However, prior to ECMAScript 6, this is a bit more complicated, since no equivalent of the Number.isInteger() method is provided.
The simplest and cleanest pre-ECMAScript-6 solution (which is also sufficiently robust to return false even if a non-numeric value such as a string or null is passed to the function) would be the following use of the bitwise XOR operator:
function isInteger(x)
{
return (x ^ 0) === x;
}
Others like Math.round() ,typeof and parseInt can be used also to find the Integer.
While this parseInt-based approach will work well for many values of x, once x becomes quite large, it will fail to work properly. The problem is that parseInt() coerces its first parameter to a string before parsing digits. Therefore, once the number becomes sufficiently large, its string representation will be presented in exponential form (e.g., 1e+21). Accordingly, parseInt() will then try to parse 1e+21, but will stop parsing when it reaches the e character and will therefore return a value of 1.

TypeScript isNaN only accepts a number

I work with WebStorm 2016.2.2, TypeScript 2.1, Node.js.
For some reason, isNaN is declared as a function that only accepts a number:
declare function isNaN(number: number): boolean;
I tried to change it to any, but it looks like it doesn't influence on the TSC. I still get the same error:
Argument of type 'string' is not assignable to parameter of type
'number'
My code (simplified):
isNaN("10");
How can I solve/workaround it?
Edit:
Notice that according to specification, isNaN's parameter can be any type: Number.isNaN()
Also: My code was simplified. I actually receive a parameter that may be either a string or a number, and if it's a string it may be either a stringy number that I would like to convert to number ("10") or a simple string ("Hello world").
I didn't want to make this question long by including my entire code, but because it caused confusion, this is my real code:
if (typeof expectedValue === "string" && !isNaN(expectedValue)) {
expectedValue = +expectedValue;
}
if (typeof actualValue === "string" && !isNaN(ctualValue)) {
actualValue = +actualValue;
}
switch (this.operator) {
case Operator.equal:
return actualValue == expectedValue;
case Operator.notEqual:
return actualValue === undefined || actualValue != expectedValue;
case Operator.greaterThan:
return actualValue > expectedValue;
case Operator.littleThan:
return actualValue < expectedValue;
case Operator.greaterOrEqual:
return actualValue >= expectedValue;
case Operator.littleOrEqual:
return actualValue <= expectedValue;
}
I advise you to implement your code differently.
The reasons:
It might be short, but it's not easy to understand what's going on
Using isNaN isn't the best option here: isNaN("") returns false as well
You better try to convert the value into a number and check if that's NaN or not (as #smnbbrv wrote):
if (typeof expectedValue === "string" && !Number.isNaN(Number(expectedValue))) {
expectedValue = Number(expectedValue);
}
Edit
You can pass your value as any:
isNaN(ctualValue as any)
To bypass the compiler check.
You should not solve it because this is how TypeScript works.
Just cast the input to number first
Number("10") // 10
Number("abc") // NaN
and then check the result with the isNan function:
isNaN(Number("abc"))
As ironically only numbers can be NaN, you need to transform strings into numbers first.
A very simple way to do this is the unary plus operator.
So you can do a simple isNaN(+"10").
Keep in mind that thing like +"", +" " and +"\n" are 0!
First of all, only values of type number can be NaN. So if the static context tells you your value is of type string for example, you can be sure that it is not a NaN. If you have a value with type string|number (which should be avoided btw) you can still decide how you handle this. Strictly speaking, the string value "foo" is not NaN, as NaN is a specific value specified in the IEEE standard for float numbers. But still, in javascript, isNaN("foo") will be true, as the function will coerect the string to a number first, and that coerection results in a NaN. Typescript tries to take advantage of types here, it tries to prevent you from using isNaN where you should not.
You can solve this by using parseInt inside your isNaN. The check isNaN will still work if the parseInt returns NaN. And your Typescript error will be solved.
if (typeof actualValue === "string" && !isNaN(parseInt(actualValue, 10))) {
actualValue = +actualValue;
}
In the accepted answer, !Number.isNaN(Number(expectedValue)) still returns true for empty string ('') and whitespace strings (' '). And converting these to number will result in 0.
I'm not a JavaScript developer, and – especially coming from .Net – it looks insane to me as well, but this is what I've done that seems to work:
private static isNumber(value: any): boolean {
return (typeof value === 'number' && !isNaN(value))
|| ((typeof value === 'string') && value.trim() != '' && !isNaN(Number(value)))
}
If you know a saner solution, be sure to edit this!
console.log(isNumber([])); // false
console.log(isNumber({})); // false
console.log(isNumber("")); // false
console.log(isNumber(" ")); // false
console.log(isNumber(" 1 ")); // true <= note
console.log(isNumber(" 1 2")); // false
console.log(isNumber("1")); // true
console.log(isNumber(1)); // true
Found this answer from Google, and reached my answer from the various answers and comments here; my answer is to use:
isNaN(Number(string))
This will correctly tell me if the string is a number.
I was previously using parseInt(), but this fails if the string is something like 123abc as parseInt just discards the letters (useful sometimes, but not here).
Note: I'm happy that Number('') evaluates to zero, but if your not, this isn't the solution!
Passing isNaN(value as unknown as number) satisfied my compiler.
In my case, I was using isNaN() to prevent "NaN" from flashing while data loaded. This allowed me to pass a string into isNaN() since the interface expected a string.

Why are my test for checking floats keeps returning false?

I created a javascript method that checks if a number is a float. Each time I test the method for a float it keeps returning FALSE. I am not sure what I am doing wrong here. Any help would be really appreciated!
Below is my code.. Thanks!
function isFloat(n){
var patt = new RegExp('[+-]([0-9]*[.])?[0-9]+');
return patt.test(n)
}
console.log(isFloat(12.40));
There's a much easier way to check if a number is a float. Just compare the floored value against the original value. If they're the same, it's an integer.
function isFloat(n) {
return Math.floor(n) !== n;
}
console.log(isFloat(1));
console.log(isFloat(1.2));
console.log(isFloat(12));
console.log(isFloat(12.4));
This will work if, and only if, you only use it on numbers. You can perform an additional check if you're worried about someone passing in non-numbers.
function isFloat(n) {
return typeof n === 'number' && Math.floor(n) !== n;
}
Or you can simplify this even further by using Number.isInteger, provided you're running an environment that supports it.
function isFloat(n) {
return typeof n === 'number' && !Number.isInteger(n);
}
console.log(isFloat(1));
console.log(isFloat(1.2));
console.log(isFloat(12));
console.log(isFloat(12.4));
console.log(isFloat('a'));
Your RegEx is wrong, it should be
/[+-]?\d+\.\d+/g
Also, as others noted, this is not the best solution for this. Use !Number.isInteger(num)
The problem is that toString does not insert '+' before a number:
12.40.toString(); // "12.4", not "+12.4"
So you could use a regular expression like
new RegExp('[+-]?([0-9]*[.])?[0-9]+');
However, I recommend Validate decimal numbers in JavaScript - IsNumeric()

Coffeescript ternary if-statement wrong logic

I have a pretty much simple logic in a return function, but it doesn't work as expected. Of course I can make the code slightly longer and solve the issue, but I want it to be as small as possible.
Here is my code:
#Return title if exists or false otherwise
getPageTitleFromMainContent = (mainContent) ->
mainContent.find('#pageTitle') ?.length ?= false
if y = (getPageTitleFromMainContent $("#mainContent"))
y.css color:red
As you see, if it finds the #pageTitle in #mainContent, it should make it red. But the function doesn't return the #pageTitle if found, it returns .length.
From js2coffee.org I see that the code is compiled into:
var getPageTitleFromMainContent, y;
getPageTitleFromMainContent = function(mainContent) {
var _ref, _ref1;
return (_ref = mainContent.find('#pageTitle')) != null ? (_ref1 = _ref.length) != null ? **_ref1 : _ref.length = false : void 0;**
};
if (y = getPageTitleFromMainContent($("#mainContent"))) {
y.css({
color: red
});
}
And it should be _ref : _ref.length = false : void 0;, not _ref**1** : _ref.length = false : void 0; .
http://jsfiddle.net/X8VjJ/1/
Thank you!
if it finds the #pageTitle in #mainContent, it should make it red
You can accomplish this with the much simpler:
$('#mainContent #pageTitle').css(color: 'red')
Since, if it doesn't find #pageTitle in #mainContent, it will try to change the css of an empty set of elements -- a no-op.
The code as you've presented it doesn't really make sense. ?. is unnecessary, as the jQuery selector will not return null or undefined if it doesn't match; it will return an empty set of elements. So it will always be returning length, which will always be a number, so the assignment will never execute, since it depends on length returning null or undefined. Which is good, since you probably don't want to set the length of the elements to false.
Finally, this isn't the ternary if statement. CoffeeScript's ternary if statement looks like this: if foo then bar else baz.
Not sure that code makes sense. You're effectively trying to assign TO the length property, unless length is defined. If it is defined, it simply returns the length property. Looks like the code and behaviour is correct, but your understanding of the existential operator and return values is wrong. If you want to return the found element you probably need to disconnect it from the length check.
Maybe something like:
getPageTitleFromMainContent = (mainContent) ->
arr = mainContent.find('#pageTitle')
if arr.length then arr else false
As Ian explained in his more elegant answer, you do not need to use the existential operator on arr (assuming jquery), since it will always be an array of elements (with zero length if not found).

string compare in javascript that returns a boolean

Is there a function in javascript that compares a string and returns a boolean? I found .match but it returns the strings that matched. I was hoping there was something else so that I would have a lesser code in comparing a string. Since I wanted to check if a string has this word and proceed else not.
thanks
You can use the RegEx test() method which returns a boolean:
/a/.test('abcd'); // returns true.
You may use type augmentation, especially if you need to use this function often:
String.prototype.isMatch = function(s){
return this.match(s)!==null
}
So you can use:
var myBool = "ali".isMatch("Ali");
General view is that use of type augmentation is discouraged only because of the fact that it can collide with other augmentations.
According to Javascript Patterns book, its use must be limited.
I personally think it is OK, as long as you use a good naming such as:
String.prototype.mycompany_isMatch = function(s){
return this.match(s)!==null
}
This will make it ugly but safe.
there is .indexOf() which will return the position of the string found, or -1 if not found
myString.indexOf(myWord) > -1
or, if you want a function:
function hasWord(myString, myWord) {
return myString.indexOf(myWord) > -1;
}
I know this isn't the exact answer you are looking for but this is always an effective way to do this.
if(var1 == var2){
//do this
}else{
//do that
};
Actually, .match()can do the trick for you because it returns an array of pattern matching strings if any, null otherwise.
Anyway, if you just want to check if a string contain another string you're more likely to use indexOf() (it will return -1 if no substring is found).
The first solution is a bit overkill for your purpose.
If on the other end you want to check for equality you can use `string1 === string2``
You can just use a compare.
if ("dog" == "cat") {
DoSomethingIfItIsTrue();
} else {
DoSomethingIfItIsFalse();
}
If anyone still has doubts ...
It was quoted by another colleague using the indexOf() method. The return of this method is either "-1", if it does not find the String in the Array, or the position of the case it finds.
To use it with the desired return, you would have to perform a check before, such as:
exampleMethod () {
const expression = ['string1', string2] .indexOf (this.exampleObject);
if (expression! = -1) {
return true;
} else return false;
}
Basically, you would take advantage of this return.
However, the includes() method can simply be used:
exampleMethode(): boolean {
return ['string1', 'string2'].includes(this.exampleObject);
}
The return of this method will do what you want in a simple way. Compares the object string with the string array you want to check, and returns a boolean.

Categories

Resources