Inigo Inigo - 2 months ago 8x
AngularJS Question

Can't set selected value of ng-options

I am trying to populate a drop-down select options list and set a default selected value using ng-model and ng-options.

I have the following code in my view:

<select ng-model="" ng-options=" for site in siteList"></select>

And in my controller:

$scope.siteList = [
{ id: 1, name: 'cycling'},
{ id: 2, name: 'walking'},
{ id: 3, name: 'holidays'}

$ = { id: 2, name: 'walking'};

The list is getting populated with the correct 3 options from the
object, but it is not selecting walking by default as I would expect? Why not?

Now, when I change this:

$ = { id: 2, name: 'walking'};

To this:

$ = $scope.siteList[1];

Now it works. Why? Isn't it the same thing?


That is because angular looks for object equality to bind it with your syntax and inyour case $scope.siteList[1] is not equal to { id: 2, name: 'walking'}; (2 objects are equal only if they point to the same reference). You can get around this in many ways, one easy way is to use track by syntax with ng-options to specify track by id, which will enable ng-option's options to be tracked by the specified property of the bound object rather than the object reference itself.

<select ng-model="" 
    ng-options=" for site in siteList track by"></select>

You could also use the syntax to minimally set the ng-model to specify only the id using select as part in the syntax:-


ng-options=" as for site in siteList"

and model would just be:-

 $ = 2;

angular.module('app', []).controller('ctrl', function($scope){
  $scope.thisTour = {};
 $scope.siteList = [
        { id: 1, name: 'cycling'},
        { id: 2, name: 'walking'},
        { id: 3, name: 'holidays'}

    $ = { id: 2, name: 'walking'};
<script src=""></script>
<div ng-app="app" ng-controller="ctrl">
  <select ng-model="" ng-options=" for site in siteList track by"></select>

From documentation

trackexpr: - Used when working with an array of objects. The result of this expression will be used to identify the objects in the array. The trackexpr will most likely refer to the value variable (e.g. value.propertyName). With this the selection is preserved even when the options are recreated (e.g. reloaded from the server).

Also worth noting:

Do not use select as and track by in the same expression. They are not designed to work together.