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){}

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.