0

I'm using LoDash to create statistics out of some records in a IndexedDB.

$scope.refreshStats = function() {

    var dataByMonth = _.groupBy($scope.stats, function(record) { 
        return moment(record.date).format('MMMM YYYY'); 
    });

    dataByMonth = _.mapValues(dataByMonth, function(month) {
        var obj = {};
        obj.Cars = _.groupBy(month, 'car');
        obj.Drivers = _.groupBy(month, 'driver');

        _.each(obj, function(groupsValue, groupKey) {
            obj[groupKey] = _.mapValues(groupsValue, function(groupValue) {
                return _.reduce(groupValue, function(sum, trip) {
                    sum['trips']++;
                    sum['duration']+= moment.utc(trip.duration, 'HH:mm:ss');
                    sum['total'] = moment.utc(sum.duration). format('HH:mm:ss')
                    return sum;
                }, {trips: 0, duration: 0, total:0})
            });
        })
        return obj;
    });
    $scope.statistics = dataByMonth;
    console.log($scope.statistics);
};

The result from my function is a collection of nested objects which key is always a month and a year:

Object {
    July 2016: Object, 
    August 2016: Object, 
    September 2016: Object, 
    October 2016: Object
}

The problem is that when I display it in the frontend, the first ng-repeat grouped by months monthName will get ordered alphabetically (displaying August-July-September-October), and so far I didn't figure out how to order it by date.

Here's how the ng-repeat looks like:

<div ng-repeat="(monthName, monthValue) in statistics">

    {{monthName}}

</div>

Is there any way to use orderBy:date when the date is they key of the object?

EDIT

The question is not repeated as my problem is the need to identify the Key as Date and then order by it. I haven't been able to solve this problem with the answers to the referred question.

Eric Mitjans
  • 2,149
  • 5
  • 40
  • 69

1 Answers1

2

Key order for object in JS can not be relied on, you'll have to convert your data in to a {date: , value: } object and sort it.

First step, conversion:

var step1 = _.map(_.pairs(dataByMonth), _.partial(_.zipObject, ['date', 'value'] ));

next you need to sort them:

var step2 = _.sortBy(step1, function(value){
  return new Date(value.date);
});

step2 holds your sorted value

$scope.statistics = step2;

you can use it in your ng-repeat

<div ng-repeat="montStats in statistics">

    {{monthStats.date}}

</div>

You can further optimize your code by:

Keeping the date as a real date and avoid the parsing by each sort iteration.

Chain the operations:

_(dataByMonth).pairs().map(
  _.partial(_.zipObject, ['date', 'value'])).sortBy(function(value){
    return new Date(value);
  }).value();
Meir
  • 14,081
  • 4
  • 39
  • 47