javascriptangularjsangular-componentsangularjs-digest

Infinite $digest() loop AngularJS with filter expression on html attribute


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.


Solution

  • 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