The selectbox value is not updated if I use track by in ng-options

50 Views Asked by At

When I use track by in ng-options, Angular doesn't update the selectbox value even if I choose one of the values in the selectbox. After second try, it works as expected even though the model value is already set.

var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function ($scope) {
    $scope.items = [
        ['ali', 'ali']
    ];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<div ng-app="myapp">
    <fieldset ng-controller="FirstCtrl">
        value: {{selected}} <br><br>
        <select 
            ng-options="item[0] as item[1] for item in items track by item[0]"
            ng-model="selected"></select>
  </fieldset>
</div>

3

There are 3 best solutions below

0
On BEST ANSWER

It's actually explained in the docs (https://docs.angularjs.org/api/ng/directive/ngOptions - look for the paragraph "select as and track by")

It seems that you cannot use track by together with some select as expressions.

But it works if for example you use ng-options="item as item[1] for item in items track by item[0]" instead of ng-options="item[0] as item[1] for item in items track by item[0]"

See https://jsfiddle.net/b9upojmb/1/

0
On

Objective of track by is to use it with object not array elements. I would recommend you to use object. Here's an example

var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function ($scope) {
    $scope.items = [
        { id :1, value : 'ali'},
        { id :2, value : 'ahmed'}
    ];
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<div ng-app="myapp">
    <fieldset ng-controller="FirstCtrl">
        value: {{selected}} <br><br>
        <select 
            ng-options="item as item.value for item in items track by item.id"
            ng-model="selected"></select>
  </fieldset>
</div>

0
On

As commented track by needs an array of objects then you can track by any object properties

var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function ($scope) {
$scope.items = [
                    { name : "ali" },
                    { name : "ben" },
                    { name : "bill" }
               ]

});
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.js"></script>
<div ng-app="myapp">
    <fieldset ng-controller="FirstCtrl">
        value: {{selected}} <br><br>
        <select 
            ng-options="item as item.name for item in items track by item.name"
            ng-model="selected"></select>
  </fieldset>
</div>