2

An attempt to use a filter on a directive with isolate scope:

<div tags="p.tags | refTags"></div>

Causes an infinite loop in the $digest cycle:

This error occurs when the application's model becomes unstable and each $digest cycle triggers a state change and subsequent $digest cycle. Angular detects this situation and prevents an infinite loop from causing the browser to become unresponsive.

.directive 'tags', ->
    restrict: 'A'
    scope:
        tags: '='
    templateUrl: 'partials/tags.html'


.filter 'refTags', ->
    (tags) ->
        ['a filtered', 'array of values']

partials/tags.html

<ul>
    <li ng-repeat="tag in tags">{{tag.tag}}</li>
</ul>

p.tags in the controller

p.tags = ['HTML5', 'CSS', 'JavaScript', 'Angular JS', 'Backbone JS', 'Node JS', 'SASS + Compass', 'Oragami', 'Running', 'Cat Food', '#catfood']

Is this behavior normal?

  1. Can a filter not be use on a value passing in to the isolate scope of a directive?
  2. Is there a workaround for this? I need to filter the arrays values
  3. Is there another solution with a different design?
Stewie
  • 60,366
  • 20
  • 146
  • 113
TaylorMac
  • 8,882
  • 21
  • 76
  • 104

2 Answers2

5

I don't think it is a directive problem but a filter problem. 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.

I suggest you to start by returning the same array, i.e. input = output. Check if all works as expected. After that add the relevant condition.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
  • Agreed, if you're just returning an arbitrary array in filter, Angular doesn't recognize the model your filter is returning and digest keep on going. – Jonathan Rowny Jan 13 '14 at 20:05
  • Thank you Maxim and Jonathan. That clears things up. Excellent – TaylorMac Jan 13 '14 at 20:06
  • @TaylorMac if you ever do a `console.log()` on a model, you'll see Angular assigns a bunch of stuff to it to keep track of it. That's another reason primitives are difficult for Angular because it can't assign its meta data to a string. – Jonathan Rowny Jan 13 '14 at 20:11
1

This question provides an actual workaround.

In short, pass the filter you want to use into your directive as well, and then use it there.

Community
  • 1
  • 1
  • You should definitely link the original question/answer, but pull the salient details into this question and apply it directly to the problem presented here. Or, if the questions are identical, you can mark one a duplicate. – Nathaniel Ford Dec 12 '15 at 00:09