Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
102
rated 0 times [  107] [ 5]  / answers: 1 / hits: 18857  / 11 Years ago, fri, november 8, 2013, 12:00:00

I'm getting the below error in my angular code. I'm struggling to understand why the function getDrawWithResults would cause a digest cycle as there don't seem to be any side effects? It just returns items from a list that have a property set to true.



The error only occurs when the first use of getDrawWithResults is on the page, if I remove, the error stops.



Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!
Watchers fired in the last 5 iterations: [[getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []],[getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []],[getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []],[getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []],[getDrawsWithResults(selectedLottery.draws); newVal: []; oldVal: []]]


This is my code:



HTML



<h4 ng-cloak ng-hide=getDrawsWithResults(selectedLottery.draws)>Results of Selected Lottery</h4>

<div class=con ng-repeat=draw in getDrawsWithResults(selectedLottery.draws) ng-cloak>
<h5 class=con__header>[[ draw.date|date:'EEEE d MMMM yyyy - H:mm' ]]</h5>
<div class=balls-list__outer con__row>
<div class=balls-list>
<div class=balls-list__ball__outer ng-repeat=b in draw.results>
<button class=balls-list__ball btn btn-con>[[ b ]]</button>
</div>

</div>
</div>
</div>


JS



// return list of draws with results
$scope.getDrawsWithResults = function(draws) {
return _.filter(draws, function(draw){
return draw.results && draw.results.length > 0;
});
}

More From » angularjs

 Answers
141

I assume _.filter returns a new array instance everytime it is run. This causes angular's implicit $watches like:



ng-hide=getDrawsWithResults(selectedLottery.draws)


and



ng-repeat=draw in getDrawsWithResults(selectedLottery.draws)


to think that the model has changed so it needs to digest again.



I would implement a filter



app.filter('withResults', function() {
return function(draws) {
return _.filter(draws, function(draw){
return draw.results && draw.results.length > 0;
});
}
})


and apply it like that (see EDIT below):



ng-hide=selectedLottery.draws | withResults


and



ng-repeat=draw in selectedLottery.draws | withresults


EDITED after discussion in comments



The actual problem is this binding:



ng-hide=getDrawsWithResults(selectedLottery.draws)


ng-hide registers a watch which will fire forever since the reference of the filtered array always changes. It can be changed to:



ng-hide=getDrawsWithResults(selectedLottery.draws).length > 0


and the corresponding filter:



ng-hide=(selectedLottery.draws | withResults).length > 0


ng-repeat does not have the same problem because it registers a $watchCollection.


[#74407] Thursday, November 7, 2013, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
georginaariao

Total Points: 626
Total Questions: 112
Total Answers: 112

Location: Burkina Faso
Member since Thu, Dec 15, 2022
1 Year ago
;