11

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.

JoshDM
  • 4,939
  • 7
  • 43
  • 72
Kevin Beal
  • 10,500
  • 12
  • 66
  • 92
  • 1
    http://stackoverflow.com/questions/2801601/why-does-typeof-nan-return-number – RonSper Jun 27 '13 at 19:42
  • 6
    What doesn't work? '95.55' is not a number, it is a string. Likewise, multiplying a string by a number will, javascript will parse/cast that string as a number and attempt do do the operation. Concatenation works differently, since number + string will be a string (javascript casts the number as a string). – Brad M Jun 27 '13 at 19:42
  • @BradM I added to my question to help clarify the problem. – Kevin Beal Jun 27 '13 at 19:46
  • `angular.isObject()` doesn't return true if supplied `null` (as is the case with `typeof`), so this excuse of "that's how native javascript works" is a non-argument. And is not a justification for the ostensible dupe question status. – Kevin Beal Jun 04 '14 at 16:51
  • 1
    use like that: angular.isNumber(+num || num), if num is string/object/etc.. is preferred on NaN. so, it's actually check if the source is a number. – a8m Oct 06 '14 at 20:32
  • 1
    Check out http://stackoverflow.com/a/1830844/504836 for a working `IsNumeric` method. – joelnet Mar 28 '15 at 01:25
  • 2
    I vote this is not a duplicate of the linked question. This question is about the expected behavior of the angularJS isNumber method. It has nothing to do with whether or not NaN is considered a "number" type. – Dave Rager Oct 26 '15 at 21:48

3 Answers3

17

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
Paul S.
  • 64,864
  • 9
  • 122
  • 138
  • 2
    Just want to point out that this may suffer from rounding errors if you're dealing with extremely small or extremely large (string) numbers. – Paul S. Jun 27 '13 at 19:54
  • 1
    I would just add this link to an issue on angular github page, where they waived it as won't fix: https://github.com/angular/angular.js/issues/701 – Capaj Mar 09 '14 at 13:17
  • 1
    WARNING: This method returns false for valid numbers like "0.0000005" since (0.0000005).toString() == "5e-7" in JavaScript. – joelnet Mar 28 '15 at 01:17
  • @joelnet Hadn't considered those types of situations. Where would `+x.toString() === x` fail? You might be able to account for these edge cases – Paul S. Mar 28 '15 at 01:42
0

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);
}
Smeegs
  • 9,151
  • 5
  • 42
  • 78
0

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

Ram
  • 1,461
  • 1
  • 13
  • 17
  • 2
    Using `eval()` is [insanely insecure](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Never_use_eval!). – Diogo Kollross Feb 13 '20 at 13:22