Search code examples
javascriptangularjsangularjs-scopeangularjs-ng-repeatangular-ngmodel

Specifying Angular ngModel Value with ng-repeated options


I've got a select dropdown, whose options are being ng-repeated out of an object called $scope.bars.

However, my ng-model, which is set to a sub-value of $scope.bars, is not correctly choosing an option. Instead, the select box is blank by default, indicating an 'undefined' value.

Here's my HTML:

<div ng-app="programApp" ng-controller="programController">
  <label>Level: 
    <select ng-model="advancedFilters">
      <option ng-repeat="item in bars" value="item.id">{{item.name}}</option>
    </select>
  </label>
</div>

And here's my Angular code:

angular.module('programApp', [
    'programApp.controllers',
]);
angular.module('programApp.controllers', [])
    .controller('programController', ['$scope',  
    function($scope){

      $scope.advancedFilters = 1;

      $scope.bars = [
        {'name':'First',
          'id':1},
        {'name':'Second',
          'id':2},
        {'name':'Third',
          'id':3},
        {'name':'Fourth',
          'id':4},
        {'name':'Fifth',
          'id':5}];
    }]);

Because $scope.advancedFilters is equal to 1, the dropdown should display the 'First' option, because the first dropdown option has an id value of 1. Instead, the dropdown is blank, indicating a problem with ng-model.

How do I fix this?

See a Codepen here: http://codepen.io/trueScript/pen/PqbVyv


Solution

  • You are going to run into these kind of issues if you use ng-repeat for select. Try use ng-options instead. i.e

     <select ng-options="item.id as item.name for item in bars" 
             ng-model="advancedFilters">
    </select>
    

    Demo

    item.id as item.name for item in bars represents

    selectedValue as displayName for item in list

    Even if your ng-model is not defined or not one of the items in the list, you could set up a default option as well with this by doing:

    <select ng-options="item.id as item.name for item in bars" 
             ng-model="advancedFilters">
       <option value="">--Please Select--</option>
    </select>
    

    Otherwise you need to provide value as interpolated (value="{{item.id}}") when using ng-repeat, i.e

    <option ng-repeat="item in bars" 
            value="{{item.id}}">{{item.name}}</option>
    

    Demo