Reputation: 1608
I have a form used to update a record populated from a restful service.
One of the fields uses a select for a look-up value and I'm binding it to an object in my model.
The select is created correctly and choosing options makes the correct changes to my model.
The problem is when I initially load the page the select is blank.
Is there a way to set the initial value correctly without having to crawl the look-up object and match the id to get the auto-generated index position?
Or better yet, set the value to be the object instead of an auto-generated index.
<div ng-controller="MyCtrl">
Id: <input ng-model="course.id" readonly><br>
Cost: <input ng-model="course.cost" ng-required="true"><br>
Title: <select ng-model="course.courseTitle" ng-options="title.name for title in courseTitles">
</select> {{course.courseTitle.description}}<br>
Length: <input ng-model="course.length" ng-required="true"><br>
<br>
Id: {{course.id}}<br>
Cost: {{course.cost}}<br>
Title: {{course.courseTitle.name}}<br>
Length: {{course.length}}
</div>
function MyCtrl($scope) {
$scope.course = {
"id": "108",
"cost": "155",
"courseTitle": {
"description": "Description of course 37.",
"id": "37",
"name": "Course 37 Name"
},
"length": "7"
};
$scope.courseTitles = [{
"description": "Description of course 37.",
"id": "37",
"name": "Course 37 Name"},
{
"description": "Description of course 63.",
"id": "67",
"name": "Course 63 Name"},
{
"description": "Description of course 88.",
"id": "88",
"name": "Course 88 Name"}];
}
I have created a fiddle here - http://jsfiddle.net/bcarter/Jxydp/
Upvotes: 1
Views: 5989
Reputation: 5858
Use the "track by" clause of ng-options
<select ng-model="course.courseTitle"
ng-options="title.name for title in courseTitles track by title.id">
</select>
This will cause the comparison to do the check by title.id == other.id instead of title == other
Upvotes: 5
Reputation: 42031
This might be a little opinionated, but I think it'd be better to change the structure your data. Just have an array with your models
$scope.courses = [{
"cost": "155",
"description": "Description of course 37.",
"id": "37",
"name": "Course 37 Name",
"length": "8"
},{
"cost": "156",
"description": "Description of course 63.",
"id": "67",
"name": "Course 63 Name",
"length": "9"
},{
"cost": "157",
"description": "Description of course 88.",
"id": "88",
"name": "Course 88 Name",
"length": "9"
}];
Then change both ngModel
and ngOptions
in your select
element to
<select ng-model="course" ng-options="course.name for course in courses">
And then in your controller tell angular to set whatever course in your courses as the initial one
$scope.course = $scope.courses[0];
This way you don't need to worry about another object and to keep things in sync, let angular do it for you.
JSfiddle here http://jsfiddle.net/jaimem/uuCfx/1/
Upvotes: 0
Reputation: 40337
This is because you have two different objects you're working with here. You have
{
"description": "Description of course 37.",
"id": "37",
"name": "Course 37 Name"
}
defined twice, creating two different references. If you use the same object, it will work as expected. See http://jsfiddle.net/Jxydp/14/ (There's probably a better way of doing it, but it illustrates my point)
Upvotes: 1