1

I'm trying to do a filter, which will group my collection items by the determined field (like groupBy filter from angular-filter library)

app.filter('groupBySortedField', function() {
  return function(collection, property) {
    var result = {};

    angular.forEach(collection, function(item) {
      var prop = item[property];

      if (!result[prop]) {
        result[prop] = [];
      }

      result[prop].push(item);
    });

    return result;
  };
});

It's works well, but i got a lot of errors in console:

Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached.

Look at the example with opened console http://plnkr.co/edit/HFlB7VTMCe2GnM3SUirs?p=preview

How to fix it?

Deadly
  • 2,034
  • 6
  • 24
  • 32
  • 1
    See http://stackoverflow.com/questions/16507040/angular-filter-works-but-causes-10-digest-iterations-reached or http://stackoverflow.com/questions/22638089/angularjs-filter-triggers-infinite-digest-loop – Daniel Beck Nov 23 '15 at 18:08
  • 1
    ...and the solution you want is https://github.com/a8m/angular-filter#groupby which avoids the infinite digest loop by memoizing previous return values – Daniel Beck Nov 23 '15 at 18:13
  • @DanielBeck thank you! angular-filter doesn't satisfy my requirements, i need to modify it a bit, but _.memoize works like a charm! Please left an answer and i will accept it! – Deadly Nov 23 '15 at 18:48

1 Answers1

0

I totally agree with the given answer of Daniel.

Just for a better understanding I would like to show here that a simple solution could be reached if one can do the ordering before any bindings and watchers are active.

// Code goes here

var app = angular.module('test', []);

app.controller('TestCtrl', ['$scope', function($scope) {
  var events = [{
      startDate: new Date('Tue Nov 24 2015 03:05:00'),
      name: '111'
    }, 
    {
      startDate: new Date('Tue Nov 24 2015 03:05:00'),
      name: '222'
    },
    {
      startDate: new Date('Tue Nov 24 2015 04:05:00'),
      name: '333'
    },
    {
      startDate: new Date('Tue Nov 24 2015 04:05:00'),
      name: '444'
    }
  ];

  $scope.orderedEvents = getEvents(events,'startDate');
  
  function getEvents (collection,property) {
    var result = {};
    angular.forEach(collection, function(item) {
      var prop = item[property];

      if (!result[prop]) {
        result[prop] = [];
      }

      result[prop].push(item);
    });

    return result;
    
  }
}]);
<!DOCTYPE html>
<html>

<head>
  <script data-require="angular.js@*" data-semver="1.4.7" src="https://code.angularjs.org/1.4.7/angular.js"></script>
  <link rel="stylesheet" href="style.css" />
  <script src="script.js"></script>
</head>

<body ng-app="test" ng-controller="TestCtrl">
  <ul ng-repeat="(startDate, eventsList) in orderedEvents">
    <li>{{eventsList[0].startDate}}</li>
    <li ng-repeat="event in eventsList">{{event.name}}</li>
  </ul>
  
</body>

</html>

demo