1

I am pulling a JSON of US states with their key codes, wherein the key is their state code, like NY, and value is the name of the state, like New York. In the <select> dropdown, I am having trouble ordering it alphabetically by value even after doing orderBy: value (I also tried with 'value'). It is always getting ordered by key for some reason.

Because of this, bugs like option North Carolina appearing before Nebraska, is happening.

Reproducing the problem here:

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', [ '$scope', function($scope){

  var data = {
    "dropdowns": {
      "RI": "Rhode Island",
      "HI": "Hawaii",
      "NY": "New York",
      "GA": "Georgia",
      "NV": "Nevada",
      "TN": "Tennessee",
      "CA": "California",
      "OK": "Oklahoma",
      "ME": "Maine",
      "VA": "Virginia",
      "MI": "Michigan",
      "OH": "Ohio",
      "DE": "Delaware",
      "ID": "Idaho",
      "FL": "Florida",
      "IA": "Iowa",
      "MD": "Maryland",
      "MA": "Massachusetts",
      "SC": "South Carolina",
      "AR": "Arkansas",
      "UT": "Utah",
      "IL": "Illinois",
      "IN": "Indiana",
      "CT": "Connecticut",
      "DC": "District of Columbia",
      "MN": "Minnesota",
      "KY": "Kentucky",
      "WI": "Wisconsin",
      "AZ": "Arizona",
      "MO": "Missouri",
      "KS": "Kansas",
      "OR": "Oregon",
      "MS": "Mississippi",
      "LA": "Louisiana",
      "NH": "New Hampshire",
      "WA": "Washington",
      "NJ": "New Jersey",
      "NM": "New Mexico",
      "AK": "Alaska",
      "TX": "Texas",
      "AL": "Alabama",
      "CO": "Colorado",
      "PA": "Pennsylvania",
      "NC": "North Carolina",
      "NE": "Nebraska"
    }
  };

  $scope.retailStates = data.dropdowns;

}]);
<!DOCTYPE html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
    <meta charset="utf-8">
    <title>JS Bin</title>
  </head>
  <body ng-app='myApp'>
    <div ng-controller="MyCtrl">
      <select>
        <option value="">Select</option>
        <option ng-repeat="(key,value) in retailStates | orderBy: value" value="{{key}}">{{value}}</option>
      </select>
    </div>
  </body>
</html>

How do I fix this?

Please feel free to suggest me an alternate solution if you know of using ng-options.

Rahul Desai
  • 15,242
  • 19
  • 83
  • 138

2 Answers2

2

The Angular team has said that it doesn't recommend using ng-repeat over the keys of an object, and even regrets adding that functionality. The simplest solution is probably just to transform the object into an array.

var myApp = angular.module('myApp',[]);

myApp.controller('MyCtrl', [ '$scope', function($scope){

  var data = {
    "dropdowns": {
      "RI": "Rhode Island",
      "HI": "Hawaii",
      "NY": "New York",
      "GA": "Georgia",
      "NV": "Nevada",
      "TN": "Tennessee",
      "CA": "California",
      "OK": "Oklahoma",
      "ME": "Maine",
      "VA": "Virginia",
      "MI": "Michigan",
      "OH": "Ohio",
      "DE": "Delaware",
      "ID": "Idaho",
      "FL": "Florida",
      "IA": "Iowa",
      "MD": "Maryland",
      "MA": "Massachusetts",
      "SC": "South Carolina",
      "AR": "Arkansas",
      "UT": "Utah",
      "IL": "Illinois",
      "IN": "Indiana",
      "CT": "Connecticut",
      "DC": "District of Columbia",
      "MN": "Minnesota",
      "KY": "Kentucky",
      "WI": "Wisconsin",
      "AZ": "Arizona",
      "MO": "Missouri",
      "KS": "Kansas",
      "OR": "Oregon",
      "MS": "Mississippi",
      "LA": "Louisiana",
      "NH": "New Hampshire",
      "WA": "Washington",
      "NJ": "New Jersey",
      "NM": "New Mexico",
      "AK": "Alaska",
      "TX": "Texas",
      "AL": "Alabama",
      "CO": "Colorado",
      "PA": "Pennsylvania",
      "NC": "North Carolina",
      "NE": "Nebraska"
    }
  };

  $scope.retailStates = [];
  for(var key in data.dropdowns){
     $scope.retailStates.push({"key": key, "value": data.dropdowns[key] }); 
  }
  

}]);
<!DOCTYPE html>
<html>
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.10/angular.min.js"></script>
    <meta charset="utf-8">
    <title>JS Bin</title>
  </head>
  <body ng-app='myApp'>
    <div ng-controller="MyCtrl">
      <select>
        <option value="">Select</option>
        <option ng-repeat="state in retailStates | orderBy: 'value'" value="{{state.key}}">{{state.value}}</option>
      </select>
    </div>
  </body>
</html>
Community
  • 1
  • 1
Patrick Steadman
  • 728
  • 7
  • 11
1

Parameters passed to orderBy need to match a name of a property in an array of objects this means your data will need to be changed to look like this

$scope.retailStates = [ { stateCode:"RI", stateName:"Rhode Island"},
                        { stateCode:"HI", stateName:"Hawaii"}
                      ];

and so on.

This changes your ng-repeat to

ng-repeat="retailStates in retailStates | orderBy: stateName"
Daniel
  • 1,229
  • 14
  • 24