Faust
Faust

Reputation: 15404

Why do I get an infinite digest error here?

I need to create groups of things that come as a flat array, so I can open and close grid rows using a CSS grid system.

Here's how my HTML looks:

<div ng-repeat="row in items | GroupsOf: 3" class="row">
    [show stuff]
</div>

And here's the filter I wrote to support this:

.filter('GroupsOf', function(){     
    //Takes an array of things and groups them into  
    // sub-arrays with numPerGroup things in each 
    return function(things, numPerGroup){

        var i, group = -1, groups = []          
        for(i = 0; i < things.length; i++){
            //if it's a new group:
            if(i % numPerGroup === 0){                  
                groups.push([])
                group++
            }
            groups[group].push(things[i])
        }
        return groups//
    }
})

Although things render as expected, I'm getting infinite digest error when this runs, and therefore not everything gets wired up properly. Why do I get that error, and how do I fix the filter to work w/o erring?

I'd really prefer to do this as a filter rather than grouping the data in the controller, but I'll go the later route if someone can explain to me why it's just not achievable as a filter.

Upvotes: 3

Views: 119

Answers (1)

maioman
maioman

Reputation: 18744

If you wanted to use $filter in the controller( which is certainly more performant and fixes the infinite $digest loop issue) you can do :

angular.module('myApp', [])
.controller('myCtrl', function($scope, $filter) {
    $scope.items = [
    'one','two','three',
    'unos','dos','tres',
    'uno','due','tre'
    ]
    $scope.grouped = $filter('GroupsOf')($scope.items , 3)
    console.log($scope.grouped)
})
.filter('GroupsOf', function(){     
//Takes an array of things and groups them into  
// sub-arrays with numPerGroup things in each 
return function(things ,numPerGroup){
    var i, group = -1, res = []          
    for(i = 0; i < things.length ; i++){
        //if it's a new group:
        if(i % numPerGroup === 0){                  
            res.push([])
            group++
        }
        res[group].push(things[i])
    }
    return res
}
})
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
  
<div ng-repeat="row in grouped" class="row">
    {{row}}
</div>


</div>

looking at the infdig documentation it seems your problem is caused by

.. binding to a function which generates a new array every time it is called.

that should be the reason $digest never finds a clean state.

Upvotes: 1

Related Questions