owenmelbz
owenmelbz

Reputation: 6584

AnglularJS - ngOptions selected option with string value for the model, but objects as options

Been trawling for hours now trying to understand how this is meant to work.

But effectively I've got

<div class="form-group">
    <?php $field = 'member_address_country'; ?>
    <label for="<?=$field?>">Country</label>
    <select class="form-control" id="<?=$field?>" ng-options="country.country_id as country.country_name for country in countries track by country.country_id" ng-model="a.<?=$field?>">
        <option value="" disabled="disabled" selected="selected">-- Select --</option>
    </select>
</div>

I've got an array of countries, stored inside $scope.countries as objects looking similar to

[
    {country_id: "1", country_name: "england"},
    {country_id: "2", country_name: "america"},
    {country_id: "3", country_name: "other"},
]

I've got an array of addresses which are in a ngRepeat labeled as a so a.member_address_country is a string, which will contain an int id. in this example its "2"

So although im using ngOptions and track by country.country_id and the value of the model is the id from country_id as expected, when the ngRepeat is rendered it just displays -- Select -- rather than picking the object from the array, based off the tracked id.

What am I doing wrong, and how can I fix this?

I've added a codepen of the issue -> http://codepen.io/owenmelbz/pen/XdxrMO?editors=1010

and another example here ->

angular.module('app', [])
  .controller('testController', function($scope) {

    $scope.a = {
      member_address_country: 100
    }

    $scope.countries = [{
      country_id: 100,
      country_name: "england"
    }, {
      country_id: 200,
      country_name: "uk"
    }, {
      country_id: 300,
      country_name: "london"
    }]

  });
<script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.min.js"></script>

<div class="form-group" ng-app="app" ng-controller="testController">
  <label for="member_address_country">Country</label>
  <select class="form-control" id="member_address_country" ng-options="country.country_id as country.country_name for country in countries track by country.country_id" ng-model="a.member_address_country">
  </select>model value is: {{a.member_address_country | json}}
</div>

Upvotes: 0

Views: 1113

Answers (2)

Mohsin Muzawar
Mohsin Muzawar

Reputation: 1212

HTML

<select ng-change="getName(a.member_address_country)" class="form-control" id="member_address_country" ng-options="country.country_id as country.country_name for country in countries" ng-model="a.member_address_country">
        </select> model value is: {{a.member_address_country| json}}
    Name after change = {{name}};

JS

    $scope.a = {
       country_id: 100,
          country_name: "england"
      }

  $scope.getName = function(countryid){
    angular.forEach($scope.countries,function(data){
      if(data.country_id == countryid){

        $scope.name = data.country_name;
      }

    });
  };

Upvotes: 1

Kraken
Kraken

Reputation: 5880

If I understand you correctly, you are wondering why you are defaulting to the option containing your placeholder text?

<option value="" disabled="disabled" selected="selected">-- Select --</option>

Two things:

  1. You don't need to include that option unless you have it there as a hook for something else.
  2. If you do want to use that, but don't want it to be displayed by defualt (which to be honest would not make a whole lot of sense to me) then remove the selected="selected" attribute.

Update

In that case, I took a look at your example. The person who asked you the question in the comment above is correct. Your variable has two different names: country & countries. Pick one or the other and make them match, and it should be good to go.

See:

You're referencing this variable country.country_id

But in your scope, you declare

$scope.countries = [
{
  country_id: 100,
  country_name: "england"
},
{
  country_id: 200,
  country_name: "uk"
},
{
  country_id: 300,
  country_name: "london"
}
]

Update 2

I think this is what you want or nearly:

ng-options="country.country_id for country in countries track by id"

Upvotes: 0

Related Questions