Yevhen Kutishchev
Yevhen Kutishchev

Reputation: 358

How to set value to model in AngularJS using select with array of objects

I'm new to AngularJS and I'm trying to solve one problem in most elegant way.

I have list that comes from server and used as the source for select tag's option's in my application. Lets assume that it's a list of authors which looks like this:

[
  { id: 1, name: 'Mark Twain' },
  { id: 2, name: 'Jack London' },
  { id: 3, name: 'Ernest Hemingway' }
]

Also I have book model which comes from and saved to server. One of book's properties is author which can be choosen by user from select dropdown. When book model is saved or fetched from server it's author field is represented as integer. Here is an example of how book model should be saved on server and how it looks when fetched:

{
  id: 324,
  title: 'Martin Eden',
  author: 2
}

book is represented as Angular's $resource in my application so whenever I want to save book model I just call it's save method.

To implement this logic I have tried to use select with ng-options directive, like this:

<select ng-options="author as author.name for author in authors track by author.id" ng-model="bookModel.author"></select>

But the problem with this approach is that when I pick author from drop down the value of author property is set to { id: 2, name: 'Jack London' } but I need it to be an author's id.

Here is a Fiddle that illustrates my problem. Try to select different values in drop down. Below the drop down you will see updated value of bookModel.author. I need it to be an author's id integer, not the object. So whenever I choose Jack London in drop down I need the value of bookModel.author to be 2, not { id: 2, name: 'Jack London' }. Otherwise I need do manipulations with data whenever book model comes from server and before I save it. I suppose that there can be a better way. Maybe it is something that can be achieved with ng-options directive?

I have tried do it this way:

<select ng-model="bookModel.author">
  <option ng-repeat="author in authors" value="{{author.id}}">{{author.name}}</option>
</select>

It's a bit closer but this way bookModel.author's value will be a string, not integer.

Also I know that I can set transformRequest and transformResponse functions for book $resource which will transform data to appropriate format. But maybe there is a better way?

Will appreciate any help!

Upvotes: 0

Views: 1097

Answers (1)

lenilsondc
lenilsondc

Reputation: 9800

You should use author.id as author.name on your ng-options like so:

<div ng-app="app">
  <div ng-controller="testController">
    <select ng-options="author.id as author.name for author in authors track by author.id" ng-model="bookModel.author"></select>
    <pre>{{bookModel.author | json}}</pre>
  </div>
</div>

Or, if you want the author's name:

<div ng-app="app">
  <div ng-controller="testController">
    <select ng-options="author.name as author.name for author in authors track by author.id" ng-model="bookModel.author"></select>
    <pre>{{bookModel.author | json}}</pre>
  </div>
</div>

UPDATE 1

Updated your fiddle

Upvotes: 1

Related Questions