Search code examples
angularjsangularjs-ng-options

ng-options not behaving as expected,as documented?


No matter what I try, the ID is always passed as the value. I want the Genre.label(string) as the value...

I am trying to get my head around ng-options, i read the docs, and the examples seem straight forward, however I am getting differet results than expected.

my model for Books is

Book: {
    title: string,
    genre: string,
    description: string
}

and my model for Genre is

Genre: {
    label: string
    description: string
}

then when I use ng-init="getGenres()" to pull genres into my scope, I EXPECT using

ng-options="genre.label for genre in genres track by genre.label" 

will use the LABEL for each iteration and populate the option value with the LABEL and as a matter of fact - Inspect Element does show that - it looks like this:

<option label="Sci-fi" value="Sci-fi">Sci-fi</option>

My DATA however ends up looking like this:

_id : 5a2f...5691
genre : "5a2f552765226c3018be9878"
title : "Blah Blah"

Here is the form in context:

<form ng-submit="addBook()" ng-init="getGenres()" >
    <div class="form-group" >
        <label>Title</label>
        <input type="text" class="form-control" ng-model="book.title" placeholder="Title" >
    </div>
    <div class="form-group" >
        <label>Genre</label>
        <select class="form-control" ng-model="book.genre"
                ng-options="genre.label for genre in genres track by genre.label" >
            <option value="">-- choose genre --</option>
        </select>
    </div>
</form>

Here is the COLTROLLERs getGenres:

// get genres
$scope.getGenres = function() {
    $http.get('/api/genres')
    .success(function(response) {
        $scope.genres = response;
    });
}

it returns:

[{
    "_id": "5a2f5.....a065b",
    "label": "Sci-fi",
    "description": "Dealing with subject matter that combines fictional worlds and science, both real and theoretical."
}, {
    "_id": "5a2f5.....9877",
    "label": "Romance",
    "description": "Topics with amorous overtone, undertones and toneless rantings. Matters of the heart. Emotional folly and frolic."
}, {
    "_id": "5a2f5.....9878",
    "label": "Suspense",
    "description": "Events dealing with an arousal of anticipation and dread, mostly in equal parts."
}, {
    "_id": "5a2f5.....9879",
    "label": "Gobbeldegook",
    "description": "nonsensical gibberish. blather, post-moderistic drivel."
}, {
    "_id": "5a2f5.....987a",
    "label": "Drama",
    "description": "Drama Drama Drama Drama Drama Drama Drama"
}, {
    "_id": "5a2f5.....987b",
    "label": "NonFiction",
    "description": "Real life crap. No fakery or literary license, this is REAL!"
}]

Any help is much appreciated -cheers


Solution

  • you should use like this:

        <select class="form-control" ng-model="book.genre"
                ng-options="genre.label  as genre.label for genre in genres track by genre.label" >
            <option value="">-- choose genre --</option>
        </select>
    

    If you don't use genre.label as , the genre will be used as the model in this case.
    The expression BEFORE as, which is genre.label, will be used as model value.
    The expression after as, which is genre.label will be used as displayed value in options.