15

Note the title of this question has changed to one that's more focused to the exact problem. See the comment stream to follow how it came about that I realized the problem is that AngularJS does not seem to handle {{ isNaN() }}

I have the following in my HTML:

xx {{ option.selectedSubject }} yy {{ (option.selectedSubject == null) }} zz

and I also tried:

xx {{ option.selectedSubject }} yy {{ option.selectedSubject == null }} z

and:

xx {{ option.selectedSubject }} yy {{ option.selectedSubject === null }} zz

Can someone help explain to me why I get the following for each of the above when I view my page:

xx null yy false zz

Update 1 I tried the following:

aa {{ option.selectedSubject === "null" }} bb {{ option.selectedSubject == "null" }} cc

and it gives this:

aa false bb false cc

Update 2 I am not sure if this helps but here's what populates the values of option.selectedSubject. In this case there's nothing in local storage:

$scope.option.selectedSubject = parseInt(localStorage.get('selectedSubject'));

When I check the value of $scope.option.selectedSubject it is NaN

Samantha J T Star
  • 30,952
  • 84
  • 245
  • 427
  • What are you hoping to see? – Vincent Ramdhanie Dec 19 '13 at 17:38
  • 1
    Any chance you're setting `option.selectedSubject` to "null" instead of `null`? Check out: http://jsfiddle.net/y3xzB/1/ – KayakDave Dec 19 '13 at 17:44
  • you might be doing === instead of == with "null" instead of `null` http://jsfiddle.net/y3xzB/1/ – Bro Dec 19 '13 at 17:49
  • 1
    I added another test for "null" and the output is shown in the question now. – Samantha J T Star Dec 19 '13 at 17:50
  • sry http://jsfiddle.net/y3xzB/2/ – Bro Dec 19 '13 at 17:52
  • Could there be extra characters in `option.selectedSubject`? For instance "null "(note the extra space). That can produce what you're seeing: http://jsfiddle.net/y3xzB/3/ – KayakDave Dec 19 '13 at 17:57
  • See my comment to the answer by Michael. Here it shows the output when I did {{ option }} It just shows :null – Samantha J T Star Dec 19 '13 at 18:02
  • Can you check the length of your string. For instance add `Length: {{option.selectedSubject.length}}` to your html. If it's more than 4 then we know something else is hidden in there. – KayakDave Dec 19 '13 at 18:04
  • I tried Length: {{option.selectedSubject.length}} xxx and it gave me "Length: xxx" – Samantha J T Star Dec 19 '13 at 18:07
  • Can you reproduce it in a plnker or a fiddle? Because I can't... http://plnkr.co/edit/qXinJxY5YeYYNY4YwI1P?p=preview – Galdo Dec 19 '13 at 18:08
  • When you get this result: "xx null yy false zz" are you getting the string value "null" or literally the character null? (such that it appears like this: "xx yy false zz") – KayakDave Dec 19 '13 at 18:09
  • This is what appears: "xx null yy false zz" – Samantha J T Star Dec 19 '13 at 18:10
  • try {{ isNaN(option.selectedSubject) }} – Galdo Dec 19 '13 at 18:16
  • NaN- that makes sense now. What you're seeing is expected behavior for NaN- you just need to use a NaN test instead of testing for null and you'll be set – KayakDave Dec 19 '13 at 18:17
  • BBB {{ isNaN(option.selectedSubject) }} BBB gives: BBB BBB – Samantha J T Star Dec 19 '13 at 18:22
  • Finally had some success. I moved the isNaN outside of the {{ }} and into a function. I then called the function and passed the parameter option.selectedSubject. Inside that function I checked and it was being passed a NaN. isNotNumber: function (num) { var a = isNaN(num); the value of a is true. So it seems that I must use an external function to check the value. – Samantha J T Star Dec 19 '13 at 18:27
  • 1
    Yes this is weird. On my side it worked when I added $scope.isNaN = isNaN; in the controller. This is similar to what you did. – Galdo Dec 19 '13 at 18:30
  • Samantha and @Galdo perhaps it's browser-dependent. `$scope.isNaN = function(n) { return isNaN(n); };` should work. – Bennett McElwee Dec 22 '13 at 10:03

2 Answers2

20

The problem here is not isNaN. The problem is that you are calling a function on the $scope variable that does not exist.

Every interpolated piece of text ( '{{ text }}' ), is associated to a $scope variable and evaluated against that $scope variable.

To make things easy for you, $scope.property can be created on the fly if it doesn't exist. Anytime you use ngModel='someProperty' or {{ aPropertyName }}, then the corressponding $scope.someProperty or $scope.aPropertyName is created for you automatically if it didn't already exist. This shortcut only works with primitives, however.

Function calls are always evaluated against $scope, and never created. This is why you have to say $scope.isNaN = isNaN, as you found in your earlier comment.

Try it with any function. isArray, isNumber, etc. It won't work unless you have put a $scope.functionName = functionName in a controller somewhere.

Edit: Also, if you REALLY want to do the isNaN test right in the interpolation, you can take advantage of javascript's type system and use

{{ property != property }}

But this is bad form...

http://plnkr.co/edit/wfLqzk8QxScsJPF5qY12?p=preview

Noishe
  • 1,411
  • 11
  • 14
3

Edit : The original question was Can I have a test inside {{ }} in angularJS?, and $scope.option.selectedSubject was meant to be null and not NaN. The author should have open another question instead of changing it to a complete different one.


Answer to the original question :

You can put an expression inside your binding, hence you can test {{ option.selectedSubject == null }}. Check your scope if the result of the evaluation is not what you are expecting.

Michel
  • 26,600
  • 6
  • 64
  • 69