Search code examples
angularjsangularjs-orderby

Angularjs orderBy in ng-repeat not working as expected


I have the following div in my template:

<div ng-repeat="item in billing_history | orderBy:'-timestamp'">{{ item.date }}</div>

console.log(JSON.stringify($scope.billing_history)) gives me the following:

{
  "May, 2015":{
     "date":"May, 2015",
     "timestamp":1432921230
  },
  "March, 2015":{
     "date":"March, 2015",
     "timestamp":1427846400
  },
  "February, 2015":{
     "date":"February, 2015",
     "timestamp":1425168000
  }
}

No matter what, this is what is displayed:

February, 2015
March, 2015
May, 2015

I've tried orderBy:'-timestamp' and orderBy:'+timestamp'

I'm really not sure why this isn't working. Does anyone see anything that could be going wrong?


Solution

  • You cannot use order-by filter with an object literal (or it wont just work as expected). What you have is an object literal basically there is no specific guaranteed ordering for the keys (and so for its values). You would need to convert it to an array.

    Example:

    angular.module('app', []).run(function($rootScope) {
      $rootScope.billing_history = [{
        "date": "May, 2015",
        "timestamp": 1432921230
      }, {
        "date": "March, 2015",
        "timestamp": 1427846400
      }, {
        "date": "February, 2015",
        "timestamp": 1425168000
      }]
    })
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="app">
      <p>Reverse order:
      <div ng-repeat="item in billing_history | orderBy:'-timestamp'">{{ item.date }}</div>
      <p>Correct order:
      <div ng-repeat="item in billing_history | orderBy:'timestamp'">{{ item.date }}</div>
    </div>

    Filter is one option, but be careful, filters are very performance intensive (they run as many times every digest cycle to stabilize and so what is in the filter matters much) and for operations like this on a large object it is very tricky. So better to set up view model appropriately or convert the format in the controller itself.