Search code examples
javascriptangularjsaggregateangularjs-filter

How To Group Data By Year and Month using AngularJS' $filter


So I have the following dataset that I would like to group/aggregate by Year, Month using the dateObject property.

Dataset

$scope.dataSet = [
    {
        _id :   58b57e442bf752389a940fea,
        time    :   01:39 PM,
        status  :   Submitted,
        date    :   2017-02-28T13:39:34.955Z,
        dateObject      : {
            dayOfTheMonth   :   28,
            dayOfTheWeek    :   Tuesday,
            month   :   February,
            year    :   2017
        }
    },
    {
        _id :   58b57e442bf9820389a940fea,
        time    :   05:18 PM,
        status  :   Submitted,      
        date    :   2014-02-28T13:39:34.955Z,
        dateObject      : {
            dayOfTheMonth   :   28,
            dayOfTheWeek    :   Tuesday,
            month   :   February,
            year    :   2014
        }
    },
    {
        _id :   58b57e442bf9820389a940fea,
        time    :   05:55 AM,
        status  :   Processing,     
        date    :   2016-03-18T13:39:34.955Z,
        dateObject      : {
            dayOfTheMonth   :   18,
            dayOfTheWeek    :   Friday,
            month   :   March,
            year    :   2016
        }
    }
]  

Here is how I would like to structure the data after aggregating it:

[
    {
        '2017' : [
            'March' : [
                {
                    _id :   58b57e442bf752389a940fea,
                    time    :   01:39 PM,
                    status  :   Submitted,
                    date    :   2017-02-28T13:39:34.955Z,
                    dateObject      : {
                        dayOfTheMonth   :   28,
                        dayOfTheWeek    :   Tuesday,
                        month   :   February,
                        year    :   2017
                    }
                }
            ]
        ]
    },
    {
        '2016' : [
            'February' : [
                {
                    _id :   58b57e442bf9820389a940fea,
                    time    :   05:55 AM,
                    status  :   Processing, 
                    date    :   2016-03-18T13:39:34.955Z,
                    dateObject      : {
                        dayOfTheMonth   :   18,
                        dayOfTheWeek    :   Friday,
                        month   :   March,
                        year    :   2016

                    }
                }
            ]
        ]
    },
    {
        '2014' : [
            'February' : [
                {
                    _id :   58b57e442bf9820389a940fea,
                    time    :   05:18 PM,
                    status  :   Submitted,  
                    date    :   2014-02-28T13:39:34.955Z,
                    dateObject      : {
                        dayOfTheMonth   :   28,
                        dayOfTheWeek    :   Tuesday,
                        month   :   February,
                        year    :   2014

                    }
                }
            ]
        ]
    }
]  

$scope.dataByYear = $filter('groupBy')($scope.dataSet, 'dateObject.year')
$scope.dataByMonth = $filter('groupBy')($scope.dataSet, 'dateObject.month')

When using $filter from AngularJS (As seen above), I am able to group the dataset by year or by month. My problem is that I would like to group the dataset by Year and Month. How can I achieve that?


Solution

  • Try to use groupBy filter:

    (function(angular) {
      'use strict';
    var myApp = angular.module('app', ['angular.filter']);
    
    myApp.controller('MyController', ['$scope', '$filter', function($scope, $filter) {        
        var dataSet = [
          {_id:'1', dateObject:{year:2001,month:'February'}},
          {_id:'2', dateObject:{year:2001,month:'February'}},
          {_id:'3', dateObject:{year:2001,month:'April'}},
          {_id:'4', dateObject:{year:2001,month:'April'}},
          {_id:'5', dateObject:{year:2003,month:'October'}},
          {_id:'6', dateObject:{year:2003,month:'October'}},
          {_id:'7', dateObject:{year:2003,month:'April'}}
        ];    
            
        var filter = $filter('groupBy');
        $scope.answer = filter(dataSet, 'dateObject.year');
        for(var key in $scope.answer)
            $scope.answer[key] = filter($scope.answer[key], 'dateObject.month');
        
    }]);
    })(window.angular);
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-filter/0.5.15/angular-filter.js"></script>
    
    <body ng-app="app">
      <div ng-controller="MyController">
     <li ng-repeat="(key, value) in answer | orderBy: 'key'">
       Year: {{key}}   
         <ul>
          <li ng-repeat="(key2, value2) in value | orderBy: 'key2'">      
             Month: {{key2}}   
             <ul>
              <li ng-repeat="item in value2 | orderBy: '_id'">      
                 {{item._id}}   
              </li>
            </ul>   
          </li>
        </ul>
     </li>
    </div>
    </body>