1

When I try to pass a filter expression inside a component's attribute, e.g. (see this Plunker example as well, and the possible solutions listed below).

<todo-list todos="$ctrl.todos | filter:{type:1}"></todo-list>

I get an error on the infinite digest loop, I don't understand why:

Error: [$rootScope:infdig] http://errors.angularjs.org/1.6.3/$rootScope/infdig?p0=10&p1=%5B%5B%7B%22ms…e%2C%22type%22%3A1%2C%22%24%24hashKey%22%3A%22object%3A5%22%7D%5D%7D%5D%5D
    at eval (angular.js:38)
    at m.$digest (angular.js:18048)
    at m.$apply (angular.js:18280)
    at eval (angular.js:1912)
    at Object.invoke (angular.js:5003)
    at c (angular.js:1910)
    at Object.Pc [as bootstrap] (angular.js:1930)
    at execute (VM877 main.ts!transpiled:21)
    at f (system.js:5)
    at Object.execute (system.js:5)

Code, see Plnkr: http://plnkr.co/edit/JdiLEIyji2pHd3eeNMUL?p=preview

Screenshot / Image: enter image description here

Workaround/solution: I have several workarounds/solutions:

  1. In the repo where I had the problem at first: I did <todo-list todo-items="$ctrl.todoItems" filter-by="{completed:true}"></todo-list>. For full source see here: https://github.com/aredfox/todo-angularjs-typescript/commit/e71900b96173b63ebcebb8e6c1fba00fe3997971. But I feel it's working around the problem, plus I don't understand why this triggers a $digest() cycle and why it shouldn't just work.

  2. Answer by @Mistalis https://stackoverflow.com/a/43120388/1155847 whogave a somehwat similar solution.

2 Answers 2

2

The goal of filter is to get an array as input and return another array based on some rules and conditions, where array items have the same structure as input.

The reason that causes an infinite loop in the $digest cycle is that in a filter, each digest cycle filter returns a different object that causes an additional cycle. - Source


I would suggest you to move the filter to the todoList directive:

<div ng-repeat="todo in $ctrl.todos | filter: {type:1}">
    <span>{{todo.name}}</span>
</div>

If type needs to be dynamic, pass it as a parameter/attribute to the directive.

Forked your Plunker

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks @mistalis I have a similar solution for it in my repo where I had the problem at first: <todo-list todo-items="$ctrl.todoItems" filter-by="{completed:true}"></todo-list>. For full source see here: github.com/aredfox/todo-angularjs-typescript/commit/…. But I feel it's working around the problem, I don't understand why this triggers a $digest() cycle and why it shouldn't just work? I'll also edit this in my question to reflect this. +1'ed though because indeed that's for me now the way to go :/...
The goal of filter is to get an array as input and return another array based on some rules and conditions, where array items have the same structure as input. The reason that causes an infinite loop in the $digest cycle is that in a filter, each digest cycle filter returns a different object that causes an additional cycle. This question deals well with this subject.
See github.com/angular/angular.js/issues/14039 for more about this issue.
0

There's an open issue at the angular.js repo you can follow up on in order to see the evolution regarding this problem: https://github.com/angular/angular.js/issues/14039

As a temporary solution, you could change your binding to use a shallow two way binding by changing < to =* as mentioned here: https://github.com/angular/angular.js/issues/14039#issue-133588717 Il8PNgcE?p=preview

2 Comments

If you downvote this answer, could you elaborate leaving a comment why you did so? As this involves / points to reactions of the angularjs core team themself I find this rather usefull. The biggest advantage of this workaround is that it doesn't require any refactoring once <* get's supported. We're discussing the same workaround over at: github.com/angular/angular.js/issues/15874 btw. So feel free to explain us over there aswell why you are against it.
Accepted this as correct answer as it corresponds with the solutions provided on the angularjs github issue (github.com/angular/angular.js/issues/15874) on this topic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.