2

I have an object which looks like:

{
   3019: 'Javascript',
   3046: 'Css'
}

and then, I show this object in a select like:

<select
    ng-model="langChoosed"
    ng-options="key as value for (key, value) in progLanguages"
></select>

I need to sort the items inside the select but the orderBy filter, seems to work only on arrays, how can I make it work with objects?

Pablo
  • 9,424
  • 17
  • 55
  • 78
  • 1
    Object keys are **unordered* - so no, you cannot. – tymeJV Jan 12 '17 at 16:52
  • Similar issue (but with `ng-repeat`; reduces to the same problem, however) [discussed here](https://stackoverflow.com/questions/26474920/order-by-object-key-in-ng-repeat). – ruffin Jun 30 '22 at 13:00

3 Answers3

4

NO order by can't be applied to a plain object, alternatively you can define a method in the controller to convert the object to an array

DEMO

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

app.controller("dobController", ["$scope",
  function($scope) {
    $scope.progLanguages = {
      3019: 'Javascript',
      3046: 'Css'
    };
    $scope.templatesAry = function() {
      var ary = [];
      angular.forEach($scope.progLanguages, function(val, key) {
        ary.push({
          id: key,
          lang: val
        });
      });
      return ary;
    };
  }

]);
<!DOCTYPE html>
<html ng-app="todoApp">

<head>
  <title>To Do List</title>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>

</head>


<body ng-controller="dobController">
  <select class="form-control" id="selection" ng-model="currentSelected" ng-options="selection.id as selection.lang for selection in templatesAry()  | orderBy:'lang'"></select>
</body>

</html>
Sajeetharan
  • 216,225
  • 63
  • 350
  • 396
1

Object keys are unordered - so you can't sort them. Convert your object to an array, sort it, then use it:

var sortedArrayFromObject = Object.keys($scope.progLanguages).map(function(key) {
    var obj = {};
    obj["key"] = key;
    obj["value"] = $scope.propLanguages[key];

    return obj;
});

//Sort it
sortedArrayFromObject.sort(function(a, b) {
    return +a.key - +b.key; //since all keys are strings - do an int cast with "+"
});

//Assign it
$scope.sortedArray = sortedArrayFromObject;

Use it:

<select
ng-model="langChoosed"
ng-options="item.key as item.value for item in sortedArray"></select>
tymeJV
  • 103,943
  • 14
  • 161
  • 157
  • is unnecesary to create another array with the map. Thanks for answer, I would use forEach instead of map – Pablo Jan 12 '17 at 17:16
-1

is something like this ok for you?

  var myObj = {
      3046:'Css',
    3019:'Javascript'
  };
  var keys = [];

angular.forEach(myObj, function(value,key){
    keys.push(key);
});

keys.sort();

$scope.myObj2={};
angular.forEach(keys, function(key){
    $scope.myObj2[key]=myObj[key];
});

and your html

<select
    ng-model="langChoosed"
    ng-options="key as value for (key, value) in myObj2"
></select>
Francesca
  • 248
  • 1
  • 10
  • obj2 still an object. It won't be sorted – Pablo Jan 12 '17 at 17:14
  • 1
    Yes, you are right. myObj2 must be an array where you have to push your structure `$scope.myObj2=[]; angular.forEach(keys, function(key){ $scope.myObj2.push('id':key,'value':myObj[key]); });` – Francesca Jan 12 '17 at 17:43