Angularjs groupBy + orderBy

I am using groupBy from angular-filter to group an array of objects by their date property.

<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' )">
 <h3>{{ day | date: mediumDate }}</h3>

Which produces the following:

Feb 9, 2015 
Feb 10, 2015 
Feb 11, 2015 
Feb 12, 2015 

How can I reverse the order to start from the most recent date? When I print to the console the array is printed with the order I want:

  Object {
     1423699200000: Array[1],
     1423612800000: Array[7],
     1423526400000: Array[11],
     1423440000000: Array[1]

I also wrote a custom filter to reverse the order after the groupBy:

.filter("reverseOrder", function() {
        function sortNumber(a,b) {
            return  parseInt(b) - parseInt(a);
        return function(collection) {
            var keys = Object.keys(collection).sort(sortNumber);
            var reveredCollection= {};
            var length=collection.length;
            angular.forEach(keys, function(key) {
                reveredCollection[key] = collection[key];
           return reveredCollection;

Which I have applied like this:

<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' | reverseOrder )">
     <h3>{{ day | date: mediumDate }}</h3>



Recently had the same issue. groupBy creates an object, but the orderBy needs an array, so there's a little bit of funkiness involved. I ended up getting the answer straight from their issues page where one of the authors does an excellent job of explaining it complete with code samples that was basically copy/paste for me.


It appears the proper method is to use the | toArray: true | orderBy: customMappingFunction, however, I found the performance on this to be terrible. I came up with a solution that keeps performance up and produces the correct result -- (although it does seem a bit odd!)

<div ng-repeat="(key, results) in allResults | groupBy: '-someKey' )">
    <h3>{{ key | ltrim: '-' }}</h3>
        <li ng-repeat="result in results">
            {{ result }}

For whatever reason, adding the - does force the groupBy to sort correctly, but it also adds it to the key, so we can just remove it!


We can achieve this by ordering the data in controller & converting groupBy output to Array.

In controller, order the records before sending it to view :

$ = $filter('orderBy')(events, '-date');

Now the template, receives data in sorted order. After grouping, we need to transform it to Array :

<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' | toArray:true )">
     <h3>{{ day | dayEvents[0].date: mediumDate }}</h3>

An easier way to reverse an array is to use the code from this answer

app.filter('reverseOrder', function() {
  return function(items) {
    return items.slice().reverse();

<div ng-repeat="(day, dayEvents) in events | groupBy: 'date' | reverseOrder )">
     <h3>{{ day | date: mediumDate }}</h3>

try using -

<div ng-repeat="(day, dayEvents) in events | groupBy: '-date' ">

P.S- I have not used groupBy till now anywhere!But this minus thing works well with orderBy attribute!


Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.