I'm trying to use ng-options with a <select>
to bind a numeric integer value to a list of corresponding options. In my controller, I have something like this:
myApp.controller('MyCtrl', function() {
var self = this;
var unitOptionsFromServer = {
2: "mA",
3: "A",
4: "mV",
5: "V",
6: "W",
7: "kW"
};
self.unitsOptions = Object.keys(unitOptionsFromServer).map(function (key) {
return { id: key, text: unitOptionsFromServer[key] };
});
self.selectedUnitOrdinal = 4; // Assume this value came from the server.
});
HTML:
<div ng-controller="MyCtrl as ctrl">
<div>selectedUnitOrdinal: {{ctrl.selectedUnitOrdinal}}</div>
<select ng-model="ctrl.selectedUnitOrdinal" ng-options="unit.id as unit.text for unit in ctrl.unitsOptions"></select>
</div>
And here's a jsFiddle demonstrating the problem, and some other approaches I've taken but am not happy with.
The select option is being initialized with an empty value, instead of "mV" as expected in this example. The binding seems to work fine if you select a different option -- selectedUnitOrdinal updates properly.
I've noticed that if you set the initial model value to a string instead of a number, then the initial selection works (see #3 in the fiddle).
I really would like ng-options to play nice with numeric option values. How can I achieve this elegantly?
It's because when you get the unit.id it's returning a string not an integer. Objects in javascript store their keys as strings. So the only way to do it is your approach of surrounding 4 by quotations.
Edit
Just to add Christophe's answear: easiest way to achive and maintaint it is to make a directive:
JS:
Christophe's answear wont work correctly for '0' as it returns false on "val?" test.
Maybe it's a bit messy, but result can be achieved without special functions right in ng-options
While the solution provided by Mathew Berg works it will probably break other selects that use sting-valued select options. This may be a problem if you try to write one universal directive for handling selects (like I did).
A nice workaround is to check if the value is a number (even if it is a string containing a number) and only than do the conversion, like so:
or as a controller method:
You can also define filter
number
, this filter will automatically parse string value to int: