LVarayut LVarayut - 6 months ago 213
AngularJS Question

How to set a default value to ng-options (multiple select)

I wanted to set a default value to my ng-options by using

ng-init
,
ng-model
, etc. They didn't work at all. My code is following:

Angular

var app = angular.module('role', []);

app.controller('fooController', function($scope){
$scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
$scope.user.roles = $scope.roles[0];
});


HTML

<body data-ng-app="role" data-ng-controller="fooController">
<select multiple class="form-control" data-ng-model="user.roles" data-ng-options="role.name for role in roles" required=""></select>
</body>


Here is my Plunkr.
Any help would be appreciated.

Answer

Update:

If you want to get directly to the reference used in this answer, here it is:

Reference: Initial Selection In AngularJS ng-options with track by

Here's what worked for me:

app.controller('fooController', function($scope){
    $scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
    $scope.user = {};
    $scope.user.roles = [ $scope.roles[0] ];
});

There was an error in the plunk that user wasn't initialized, apart from this, Angular would compare every object in the ng-options array to every element in the ng-model array. JavaScript comparison not Angular comparison, comparing 2 objects even with same properties in JavaScript returns false (different objects).

Plunk: http://plnkr.co/edit/ccsAVvPACnN6Qzje7HcB?p=preview

.

Now, this is not ideal. Typically you want to correlate these based on ID or so, here's another way:

In HTML, use track by to tell AngularJS to compare IDs instead of entire objects:

  <select multiple class="form-control" 
    data-ng-model="user.roles" 
    data-ng-options="role.name for role in roles track by role.id" 
    required=""></select>

Then in your controller, you can use any object without actually being in the array:

app.controller('fooController', function($scope){
    $scope.roles = [{id:1, name:"Administrator"}, {id:2, name: "Student"}];
    $scope.user = {};
    $scope.user.roles = [ {id:1, name:"Administrator"} ];
});

Plunk: http://plnkr.co/edit/NKLXrwqwk36YfhBSXILN?p=preview

Note that I didn't even need the name property. It's just for making a proper object later, but it really isn't needed for matching now, try without it!

.

I wrote a detailed tutorial with an accompanying video on this initial selection problem and its variations. It's focused on single-select but multi-select is just using an array of objects instead of one object directly.

Check it out for more understanding -- highly recommended:

Initial Selection In AngularJS ng-options with track by

.

Let me know in comments if you are still struggling with this.