Search code examples
javascriptangularjsangularjs-ng-options

set object as selected in ngoptions


Im using ngOptions for select directive like

<select class="form-control" ng-model="users.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>

im setting default in controller like

$scope.users.jobTitle = $scope.ds.jobTitle[0];

ds is a json with array jobtitle:

"jobTitle":[
  {"id":1,"value":"Service1"},
  {"id":2,"value":"Service2"},
  {"id":3,"value":"Service3"}
],

now i'm saving and getting result(console) like

jobTitle:Object
       $$hashKey:"object:173"
       id:1
     value:"Service1"

now when i'm editing, feeding the service call data like

$scope.useredit.jobTitle = data.jobTitle;

for

<select class="form-control input-sm" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>
</select>

its not setting the object as selected , instead sets the null value in first option.. what i have to do ?


Solution

  • By default, ngModel watches the model by reference, not value. This is important to know when binding the select to a model that is an object or a collection.

    One issue occurs if you want to preselect an option. For example, if you set the model to an object that is equal to an object in your collection, ngOptions won't be able to set the selection, because the objects are not identical. So by default, you should always reference the item in your collection for preselections, e.g.: $scope.selected = $scope.collection[3].

    Another solution is to use a track by clause, because then ngOptions will track the identity of the item not by reference, but by the result of the track by expression. For example, if your collection items have an id property, you would track by item.id.

    ~ Taken from the official docs regarding ngOptions

    I tested it out by using ng-options in separate select boxes and it works.

    See demo below.

    angular.module('app', [])
      .controller('TestController', ['$scope',
        function($scope) {
          $scope.ds = {};
          $scope.ds.jobTitle = [{
            "id": 1,
            "value": "Service1"
          }, {
            "id": 2,
            "value": "Service2"
          }, {
            "id": 3,
            "value": "Service3"
          }];
    
          var data = {
            jobTitle: {
              "id": 1,
              "value": "Service1"
            }
          };
    
          $scope.useredit = {
            jobTitle: data.jobTitle
          };
    
        }
      ]);
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app">
      <div ng-controller="TestController">
        <br />Without using track by in ngOptions
        <select class="form-control" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle" required>
        </select>
        <br />
        <br />
        <br />Using track by in ngOptions
        <select class="form-control" ng-model="useredit.jobTitle" name="jobTitle" data-ng-options="job as job.value for job in ds.jobTitle track by job.id" required>
        </select>
      </div>
    </div>