Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angularjs select does not mark matching model as selected

I have a problem with my ngModel in select not showing as selected. Both id and name are matching but its not working, see selectedState. Pointing model to the actual object within options array works, see selelectedState2. No idea whats going on ...

Fiddle: http://jsfiddle.net/fedorsmirnoff/b49n4Ldp/2/

<select ng-model="selectedState" ng-options="state.name for state in stateOptions"></select>

<select ng-model="selectedState2" ng-options="state.name for state in stateOptions"></select>

function MainCtrl($scope) {
 $scope.stateOptions = [
     {id: 1, name: "Alaska"},
     {id: 2, name: "Montana"},
     {id: 3, name: "Nebraska"},
     {id: 4, name: "Texas"}
  ]

 $scope.selectedState = {id: 2, name: "Montana"};

 $scope.selectedState2 = $scope.stateOptions[1];

}
like image 301
Micor Avatar asked Sep 07 '14 01:09

Micor


2 Answers

This is because each object has it's own $hashKey provided by Angular that Angular uses to determine whether they are the same. You're creating a new object (with a different $hashKey) on $scope.selectedState. The way you set it on $scope.selectedState2 is correct.

You can also use track by to make Angular track by state.id instead of the object's $hashKey:

<select ng-model="selectedState" ng-options="state.name for state in stateOptions track by state.id"></select>
like image 106
m59 Avatar answered Oct 21 '22 03:10

m59


If you are providing an object as the model which does not hold the reference to the existing list, then use track by with the unique value of your model, so that instead of using the custom unique $$hashKey, ng-options will use the property that you provide in the track by for tracking the ng-model that is being set.

  ng-options="state.name for state in stateOptions track by state.id"

Demo

Not only that it is useful in setting ng-model to any reference, but also it has a great deal of performance effectiveness as well especially when your list gets refreshed, the elements will not be removed and recreated, instead angular will just update the existing element.

Here is a very good example for this.

like image 8
PSL Avatar answered Oct 21 '22 02:10

PSL