1

Assume a list like this:

var list = [
    { status: true, name: 'Bar' },
    { status: true, name: 'Foo' },
    { status: false, name: 'John' }
];

Now I want to list only the names where status === true

So I constructed the following HTML:

<ul>
    <li ng-repeat="item in list | completed">
        {{item.name}}
    </li>
</ul>

And the code for filtering:

angular.module('MyApp')
    .filter('completed',
    function () {
        var filtered = [];
        return function (items) {
            anuglar.forEach(items, function(item) {
                if ( item.status === true ) {
                    filtered.push(item);
                }
            }
            return filtered;
        }
    });

What I noticed is that the filter function is called 3 times (which happens to be the length of the list array). But why, shouldn't this be just 1 time ? Is there something wrong in my code because otherwise it doesn't look very optimised ?!

2 Answers 2

3

The filter function runs one time per each digest (could be more than one digest in each digest cycle).

Here is a demo plunker: http://plnkr.co/edit/Gmg0m5XG0KVGJXIWcX1Q?p=preview

You can write a simple filter like this:

app.filter('completed', function() {
  return function(items) {
    return items.filter(function(item) {
      return item.status === true;
    });
  };
});

If you care about performance , you can prefilter it inside the controller:

$scope.filteredList = $scope.list.filter(function(item){ 
  return item.status === true; 
});

And then just iterate the filtered list:

<li ng-repeat="item in filteredList track by item.name">
Sign up to request clarification or add additional context in comments.

Comments

1

You don't need a custom filter for this, you could just do:

<li ng-repeat="item in list | filter:{status:true}">

or if this filter is justed used in this controller you can do the quick n' dirty:

$scope.completed = function(item) {
  return item.status === true;
});

which is used like so:

<li ng-repeat="item in list | filter:completed">

2 Comments

Not correct, the filter is executed per collection.
You're right, I was thinking about $scope.someFilter = function(item){}

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.