Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ngOptions result in options with wrong values

Tags:

angularjs

I'm trying to render select box and it does not work as expected - options values are incorrect. I checked manual, according to it the syntax for array (in my case array of objects) is

select as label for value in array

So here is what i'm doing:

data:

[{"id":"3","name":"asdasd","code":"asdads","group":"2","cost":"0"},{"id":"4","name":"adrf fg df ","code":"dasfasd","group":"2","cost":"0"}]

template:

<select ng-model="productToBuy" ng-options="item.id as item.id for item in products"></select>

rendered result:

<select ng-model="productToBuy" ng-options="item.id as item.id for item in products" class="ng-pristine ng-valid">
    <option value="0" selected="selected">3</option>
    <option value="1">4</option>
</select>

as we can see, options values does not set to items's id.

Also this may be not proper syntax when source is array but i having same results when trying like this:

<select ng-model="productToBuy" ng-options="item.id as item.id for (key, item) in products"></select>

I put this code on jsfiddle. Any help appreciated.

like image 543
SET Avatar asked Dec 18 '12 12:12

SET


3 Answers

Your datatype in the JSON object for the id is a string and the value of $scope.selected is integer. If you switch one of them to the other it would work fine!

The value of the options will still be 0 and 1, but the databinding of Angular does the trick for you and binds the value you have specified in your expression (item.id as item.name) to the ng-model of your parent element (the select element).

like image 30
Tryggve Avatar answered Nov 02 '22 23:11

Tryggve


This is the behavior of the ngOptions directive (the output you are seeing, where the value is the index of the item and not the id property that you are trying to pass in from your code sample). ngOptions will data-bind the selected option to the variable that you specified in ngModel. You would then work with your data bound variable instead of the "value" of the option element itself.

Html:

<select ng-model="selected" ng-options="item.name for item in items"></select> {{ selected }}

JS:

$scope.items = [
    {"id": "3","name":"asdasd","code":"asdads","group":"2","cost":"0"},
    {"id": "4","name":"adrf fg df ","code":"dasfasd","group":"2","cost":"0"}
];

In the above example, $scope.selected would represent the actual selected item. You can then access any of the selected item's properties: $scope.selected.name, $scope.selected.code... etc.

If you needed to preselect an item with the above example, you could do the following:

$scope.items = [
    {"id": "3","name":"asdasd","code":"asdads","group":"2","cost":"0"},
    {"id": "4","name":"adrf fg df ","code":"dasfasd","group":"2","cost":"0"}
];
$scope.selected = $scope.items[1]; // Pre-selected the 2nd item in your array

If you still need to have full control over your value attributes, you're better off using the ng-repeat directive, but remember if you do this, your selected items won't be data bound to your model.

EDIT: Note on 'select as label for value in array' syntax:

In case its helpful, what your "item.id as item.name for item in products" was doing was actually setting your variable in the ngModel directive to the value you specify in the select portion of the syntax. So what that expression is doing is setting the label as item.name, but binding $scope.selected to the value of item.id, rather than to the entire instance of item itself. So if your first item in the examples above was selected, $scope.selected would be equal to "3". It doesn't actually change the value attribute of the option element itself.

like image 171
Alex Klock Avatar answered Nov 03 '22 00:11

Alex Klock


If you don't need ng-model of select element and you want to use selected value of select element, then implement it in this way:

<select>
  <option ng-repeat="item in items" value="{{item.value}}">
    {{item.text}}
  </option>
</select>
like image 25
Ali Gonabadi Avatar answered Nov 02 '22 22:11

Ali Gonabadi