user3871
user3871

Reputation: 12708

Angular filter running more times than expected

I made a filter to sort questions by category.

I am trying to figure out why my Angular filter is running more times than the input value.

First issue: The filter is run before questions are populated:

enter image description here

Then run again when there exists a question object:

enter image description here

Second Issue: My directive's scope.questions array only contains a single question object, yet the filter is running 6 times? Why is this?

Directive HTML snippet:

    <div class="category-filter">
        <div ng-repeat="(k, v) in catfilters" class="question">
            <input type="checkbox" ng-init="checked=true" ng-model="catfilters[k]">{{ k }}
        </div>
    </div>

Loop:

    <div class="question-category">
        <li ng-repeat="q in questions | bycategory:catfilters" class="question">
            {{q.question.category.category}}
        </li>
    </div>

Directive JS: snippet

    scope.questions = args;

    console.log(scope.questions.length); //Length == 1
    /*
        Dynamically add question filters
     */
    scope.questions.forEach(function (k, v) {
        scope.catfilters[k.question.category.category] = true;
    });

Filter:

    filter('bycategory', function() {
        return function (questions, catfilterObj) {

            console.log('Q', questions); // Called 6 times

            var items = {
                categories: catfilterObj,
                out: []
            };

            angular.forEach(questions, function (value, key) {
                if (this.categories[value.question.cat_id] === true) {
                    this.out.push(value);
                }
            }, items);
            return items.out;
        };
    }

Upvotes: 2

Views: 1784

Answers (1)

JLRishe
JLRishe

Reputation: 101652

As @charlietfl points out, your angular expressions will continue to be called until the scope stabilizes.

This shouldn't be a concern unless you observe it to be causing performance problems, but if you are concerned, you could elminate some of the unnecessary operations in your filter:

filter('bycategory', function() {
    return function (questions, catfilterObj) {

        console.log('Q', questions); // Called 6 times

        return Array.prototype.filter.call(questions, function (value) {
            return catfilterObj[value.question.cat_id] === true;
        });
    };
})

Upvotes: 1

Related Questions