Angular.js: ng-select with (integer)ng-model and (object)ng-options

Created on 9 Sep 2014  路  11Comments  路  Source: angular/angular.js

In JavaScript you cannot have an object with integers as keys (they will always be typecast to String).

If you have a ng-select with ng-model as Integer and ng-options as Object, you'll never get the select to have a default value since Angular seems to use a STRICT comparison between the ng-option's values and the ng-model value.

Example (see in Plunker):

$scope.myOptions = {
    "1": "Value 1",
    "2": "Value 2",
    "3": "Value 3"
};
$scope.myModel = 2; // note it's an Integer
// replacing this with "2" will fix the issue

Then you'd have your html:

<select ng-model="myModel" ng-options="key as value for (key, value) in myOptions"></select>

That being said, ng-select should _always_ typecast the ng-model value as String when it's dealing with Object Data Sources (since those objects can't have integers as keys), or simply use non-strict comparison between the two.

low invalid confusing bug

Most helpful comment

<select ng-options="key*1 as value for (key,value) in values"> works as well.

All 11 comments

Same issue. It would be useful to use non-strict comparison. Even affect behavior through options.

Oh my ... looks like this was unintentionally fixed in 1.3.0-rc.5, and then I broke it again in https://github.com/angular/angular.js/commit/9e305948e4965fb86b0c79985dc6e8c59a9c66af, because it caused other problems.

Thing is that keys really are strings. So if you are going to match against a key then you must match a string. Even if we did use non-strict comparison to match numbers to strings, as soon as you click on an option the model is going to change to a string, since we have no way of knowing that you really wanted it to be a number.

@petebacondarwin, IMHO changing it to a string upon clicking the option is still better than breaking the entire _selected_ functionality. Thanks anyway. Cheers!

Here is a better solution: http://plnkr.co/edit/7Vw21K?p=preview

I agree there are workarounds, but sometimes sanitizing nested objects isn't as practical when you're dealing with KBs of data that are coming from a webservice somewhere, especially considering you have to do it twice (on display and on POST). Anyway, it's just a suggestion, not necessarily a blocker. Thanks for your input!

Here is a much better solution that really does work: http://plnkr.co/edit/VT8KTS?p=preview

<select ng-options="key*1 as value for (key,value) in values"> works as well.

I was running into the problem when using angular with a form generated in zend and a custom object property (integer) in the ng-model binding. While petebacondarwin's first solution would probably address it, I found it was easier just to force the property to a string before angular rendered the select. e.g.
$scope.list.ListtypeId = '' + $scope.list.ListtypeId;

@Narretz This issue is so tricky, can you give a solution to easily switch mode bwtween nonstrict and strict mode?

@ccrabb +1

Was this page helpful?
0 / 5 - 0 ratings