AngularJS: Sometime OrderBy does not work in ng-repeat

You must noticed that sometime OrderBy does not works, sometime works very nicely.

For example: if you have the data with following structure:
JavaScript

$scope.friends = [
      { name: 'John', phone: '555-1212', age: 10 },
      { name: 'Mary', phone: '555-9876', age: 19 },
      { name: 'Mike', phone: '555-4321', age: 21 },
      { name: 'Adam', phone: '555-5678', age: 35 },
      { name: 'Julie', phone: '555-8765', age: 29 }
];

Then it works if you code use the following code:
HTML

<tr ng-repeat="friend in friends | orderBy:'-age'">
      <td>{{friend.name}}</td>
      <td>{{friend.phone}}</td>
      <td>{{friend.age}}</td>
    </tr>

But if your data structures changes a bit as follows:
JavaScript

$scope.peoples = [{
      'friend':{ name: 'John', phone: '555-1212', age: 10 },
      'relative':{ name: 'Mary', phone: '555-9876', age: 19 },
      'cousin':{ name: 'Mike', phone: '555-4321', age: 21 },
      'uncle':{ name: 'Adam', phone: '555-5678', age: 35 },
      'aunt':{ name: 'Julie', phone: '555-8765', age: 29 }
}];

HTML

<tr ng-repeat="people in peoples | orderBy:'-age'">
      <td>{{people.name}}</td>
      <td>{{people.phone}}</td>
      <td>{{people.age}}</td>
</tr>

Now, order by will not. This is because, previous data structure was an array and order by works fine on array. Now it is an Object. Order by does not works on Objects. So, first you have to make this objects to an array and then it will fine.

To make this object to an array we will use an filter. Following code will create an filter for throughout the module:
JavaScript

 ng.module('yourmodule').filter('toArray', function() {
  return function(obj, addKey) {
    if (!(obj instanceof Object)) {
      return obj;
    }

    if (addKey === false) {
      return Object.values(obj);
    } else {
      return Object.keys(obj).map(function(key) {
        return Object.defineProperty(obj[key], '$key', {enumerable: false, value: key});
      });
    }
  };
});

Now you just add this filter to html code:
HTML

    <tr ng-repeat="people in peoples | toArray | orderBy:'-age'">
      <td>{{people.name}}</td>
      <td>{{people.phone}}</td>
      <td>{{people.age}}</td>
    </tr>

😉 Order by will work like magic. Cheers!

View complete code in Plnkr.co

Advertisements

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s