Diver
Diver

Reputation: 1608

How to set the initial value of a select created using ng-options with an Object as the value in angularjs

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

Answers (3)

Marc Hughes
Marc Hughes

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

jaime
jaime

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

dnc253
dnc253

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

Related Questions