Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS filter triggers infinite $digest loop

I want to use a filter expression like values | filter:value1 to hide or show a div, where values and value are both declared on the scope in the containing directive's link function.

This works as expected, except that it keeps firing off infinite digest loop errors.

See this jsbin for a demonstration: http://jsbin.com/nujineci/2/edit

What am I doing wrong? Why should these errors occur when no models are being updated by the filter?

like image 427
Nat Avatar asked Mar 25 '14 14:03

Nat


2 Answers

The answer to the problem is in the error description that Angular provides.

One common mistake is binding to a function which generates a new array every time it is called

This is basically what filter does, each time it returns new array:

// some more code
var filtered = [];
for ( var j = 0; j < array.length; j++) {
  var value = array[j];
  if (predicates.check(value)) {
    filtered.push(value);
  }
}
return filtered;

When Angular's digest loop runs for the first time it gets an array containing 'bar' and an empty array. Then Angular will run digest loop again to check if the model is stable. It will get new arrays (instances) and it will think that the model has changed. This will cause another digest loop, and so on.

You should check if your array contains values and ng-show on that. E.g. Determine whether an array contains a value

Check out this modified jsbin: http://jsbin.com/nujineci/5/edit

like image 189
lpiepiora Avatar answered Nov 03 '22 10:11

lpiepiora


May be because of using filter inside ng-show, filter gets executed in every digest cycle, and keeps checking your value is changed or not, if value is changed then it evaluates again and gives new result, otherwise it doesn't do anything (becaues angularJs uses "dirty-checking" method to find any change)

http://jsbin.com/nujineci/4/edit

check this link, i have modified

ng-show="g.values | filter:g.value1"

To

ng-show="g.values.indexOf(g.value1) != -1"

or ng-show="g.values.indexOf(g.value1) > -1" // this is same as above

indexOf returns index of item if exists in array, otherwise returns -1

I use this type of syntax, never had any problem with this

like image 5
Vamsi Avatar answered Nov 03 '22 09:11

Vamsi