Search code examples
javascriptangularjsangularjs-ng-repeatangularjs-orderby

How to sort a 1:1 object map in Angular JS ng-repeat


Is there a way to sort a 1:1 object map in angular.js using filters (or any other method) within a ng-repeat block?

I have:

obj:{
     a:3,
     c:5,
     d:1,
     g:15
}

Essentially I'd like to be able to do something like this:

<div ng-repeat="item in obj | orderBy:'value'"> {{ item.value }}</div>

I would like to be able to sort that data representation either by key or value. I know that angular OrderBy will only sort arrays so it won't sort that object. However, if I could turn that object into an array of objects with key and value as properties (preferably using a filter called 'toArray' ):

var arr = [
  { 
     key:'a',
     value:'3'
  },
  {
    key:'c',
    value:5
  },
  ....
]

then I could use something like this:

<div ng-repeat="item in obj | toArray | orderBy:'value'"> {{ item.value }}</div>

However, any attempt to write such a filter has produced a '10 $digest() iterations reached. Aborting!' error as it updates the new array of objects on every iteration.

What is the best (or any) solution to sorting a 1:1 object map without having to restructure the data in the controller?


Solution

  • Try angular-underscore which introduces underscore functions to angular.js. Then you can write code like:

    <div ng-repeat="item in values(obj) | orderBy:identity"> {{ item }}</div>
    

    to get only values; or

    <div ng-repeat="item in pairs(obj) | orderBy:last"> Key: {{ item[0] }}; Value: {{item[1]}}</div>
    

    to get both keys and values.

    It's really easy. Plunker here: http://plnkr.co/edit/Zb4XpaQUXZ8nZJqR493b?p=preview