Search code examples
javascriptangularjssortingng-options

ng-options: How can I sort by collection.item.itemName


I have a select iterating over a collection looking like this:

ctrl.countriesList = {
    'DK': {countryName: 'Denmark', preferredLanguage: 'DA'}
    'US': {countryName: 'USA', preferredLanguage: 'EN'}
}

and iteration over the object:

ng-options="country as country.countryName for country in $ctrl.countriesList"

so my dropdown is now correctly displaying the countryName property in the dropdown for each country, but it is still sorting by the ISO code value (DK, US) which in my case will often be inconsistent with the countrynames, so the sorting of countryNames in the dropdown is not alphabetical

How can I make the dropdown sort by countryName alphabetically? Thanks in advance!


Solution

  • You cannot use orderBy filter as you are using an Object Datasource and orderBy filter works for Array Data source

    See this question

    If you want to use orderBy filter make the changes to your data source as mentioned in other answers

    If you want to go with objects, I would suggest you add a function which would return the sorted values.

    In controller :

    $scope.ctrl = {//---> Source
                countriesList : {
            'DK': {countryName: 'Denmark', preferredLanguage: 'DA'},
            'US': {countryName: 'USA', preferredLanguage: 'EN'},
            'BEL':{countryName: 'Belgium', preferredLanguage: 'NL'}
          }
    }
    
    
    
     $scope.getSortedCountryList = function(){ //--> Sort Function
    $scope.sorted = {};
    Object.keys($scope.ctrl.countriesList)
            .sort(function(a,b){
              if($scope.ctrl.countriesList[a].countryName < $scope.ctrl.countriesList[b].countryName) return -1;
              if($scope.ctrl.countriesList[a].countryName > $scope.ctrl.countriesList[b].countryName) return 1;
              return 0;
             })
             .forEach(function(v, i) {
               $scope.sorted[v] = $scope.ctrl.countriesList[v];
             });
    return $scope.sorted;
    }
    

    In HTML select

    ng-options="country as country.countryName for country in getSortedCountryList()"
    

    FIDDLE