0

I've created a custom filter using AngularJS that prints out the fruits that start with a p. As far as I can tell, I've implemented the custom filter correctly.

I'm printing out a message every time the filter is called but I'm curious to why my filter is being called twice.

Looking at similar problems on stackoverflow I found one person who had a similar issue however the problem wasn't answered and was a little different.

JSFiddle Solution http://jsfiddle.net/ddemott/U3pVM/22606/

HTML Code

<body>
    <div ng-controller="ExampleCtrl" ng-app="sampleApp">
    <div class="showDiffTags" ng-repeat="val in values | myFilter:'p'">{{val.name}}</div>
    </div>
</body>

AngularJS Code

angular.module('sampleApp', []).filter('myFilter', function() {

  return function(items, firstLetter) {
    var groups = [];
    console.log("called function");
    console.log(items.length);
    for (var i = 0; i < items.length; i++) {
      if (items[i].name.substring(0, 1) == firstLetter) {
    groups.push(items[i]);
      }
    }
    return groups;
  }
}).controller('ExampleCtrl', function($scope) {
  $scope.values = [{
    name: 'apple'
  }, {
    name: 'banana'
  }, {
    name: 'orange'
  }, {
    name: 'avocado'
  }, {
    name: 'pineapple'
  }, {
    name: 'peach'
  }, {
    name: 'plum'
  }, {
    name: 'grapes'
  }, {
    name: 'mango'
  }, {
    name: 'papaya'
  }, ];
});
Ankh
  • 5,478
  • 3
  • 36
  • 40
Dale
  • 1,613
  • 4
  • 22
  • 42
  • I believe this may be the same question here: http://stackoverflow.com/questions/20798566/angularjs-calling-filter-twice-with-ng-repeat – Glen Feb 23 '16 at 16:09
  • I see. I wasn't sure of this so I didn't believe this was my answer however now that I know it is the natural cycle of how angularjs works, I can see how it would be related. – Dale Feb 23 '16 at 16:10

1 Answers1

1

That is correct behaviour and it's strongly coupled with how $digest cycle works

Every time model changes the $digest is run at least twice:

  1. After model changes it runs the watchers and updates the models
  2. To check if the first $digest made changes to model, if so another digest is called up to max ten iterations then angular throw errors.

There is nothing to worry unless you have a lot of functions in templates and unstable models (changing often)

I've updated your fiddle with simple button that updates model on scope

http://jsfiddle.net/U3pVM/22610/

<button ng-click="numModel = numModel + 1">
  update model {{numModel}}
</button>

You will see that every time you click the button filter runs twice

maurycy
  • 8,455
  • 1
  • 27
  • 44
  • But it must have something changed to trigger the digest loop.If we remove the button and in filter, we return the original items then it still run twice. – Sherlocked Nguyen Feb 23 '16 at 16:52
  • But it does change, isn't it? You return subset with filter, so you change model – maurycy Feb 23 '16 at 16:53
  • I said that if we return the original items in filter in my previous comment. You can see plnkr [here](http://plnkr.co/edit/UANI9oK4CgM8w99kpmAM?p=preview) – Sherlocked Nguyen Feb 23 '16 at 16:57
  • Sure but after initialising model `$digest` runs too – maurycy Feb 23 '16 at 17:00
  • You mean that when model initializing, it call $digest loop and after it's done, it call $digest one more time ? – Sherlocked Nguyen Feb 23 '16 at 17:11
  • No i mean you initialize model and that makes the `digest` run twice - classical two runs after change and to check if the first digest changed something – maurycy Feb 23 '16 at 19:00