Daniel Daniel - 6 months ago 14
Javascript Question

AngularJS Select preselect not working

Preselection is not working in the select field even though the objects are equal:

<select ng-show="isEditMode(todo.id)" id="assignee" name="assignee"
ng-model="todo.assignee" required
ng-options="user.name for user in users">

todo.assignee contains a user object, which should match one from users.

It seems that Angular does not recognize that the User object from todo.assignee is contained in users. Can I perform this mapping manually?

The select is shown with no value selected. I can choose a user (from users) and save the record without any problem.


$scope.todos = Todo.query();
$scope.users = User.query();


As requested in the comments. Structure of the given objects:

"id": 157,
"description": "my description 0",
"deadline": 1392073200000,
"assignee": {
"id": 34,
"name": "User 1",
"email": "user1@hotmail.com"
"comment": "my comment 0",
"done": true


"id": 34,
"name": "User 1",
"email": "user1@hotmail.com"
"id": 35,
"name": "User 2",
"email": "xxc@gmail.com"
"id": 36,
"name": "User 3",
"email": "xx@hotmail.com"

The scope of the select comes from a repeat:

<tr ng-repeat="todo in todos | filter:query | filter:{assignee:queryAssignee} | filter:queryDone" ng-class="{danger: isDue(todo)}">


According to your description:

todo.assignee contains a user object

But your options' value are user.name strings, one object and one string will never be matched.

So, replace





use ng-options="user.name as user.name for user in users"

Full Answer:

<select ng-show="isEditMode(todo.id)" 
    ng-model="todo.assignee.name" required 
    ng-options="user.name as user.name for user in users">

Plnkr: http://plnkr.co/edit/A1XdMYmACNCr3OwBuFhk?p=preview

select as label for value in array

label: The result of this expression will be the label for element. The expression will most likely refer to the value variable (e.g. value.propertyName).

you can have refer here: http://docs.angularjs.org/api/ng.directive:select


To fix the side effect, you can use option with separated value and display name

<select ng-model="todo.assignee" required>
    <option ng-repeat="user in users" value="{{user}}" ng-selected="todo.assignee.name === user.name">

Plnkr: http://plnkr.co/edit/6tzP9ZexnYUUfwAgti9b?p=preview



When you select one of option, it assign option value to model todo.assignee.name, so only change the name.

todo.assignee.name = "User 3" // like this

todo.assignee // didn't change the id & email
/* {"id": 34,
    "name": "User 1",
    "email": "user1@hotmail.com"} */

But, Now:

When you select one of option, it assign object value to model todo.assignee, so let what you want.

todo.assignee.name = { 
    "id": 36,
    "name": "User 3",
    "email": "user3@hotmail.com"
} // like this

todo.assignee // now change the whole value
/* {"id": 36,
    "name": "User 3",
    "email": "user3@hotmail.com"} */