0

I am trying to implement custom filter in angular js. The idea is that user can add some tags and each time filter is invokes.

Filter is a plain javascript object, basically it looks like this:

var filter = {color:'blue', length: 15};

Items are array of objects.

app.filter('filterByTags', function () {
    return function (items, filter) {
        debugger;
        if (!isEmpty(filter)) {
            var filtered = items;
            for (var prop in filter) {
                if (filter.hasOwnProperty(prop)) {
                    for (var i = 0; i < filtered.length; i++) {
                        if (filtered[i][prop] !== filter[prop]) {
                            filtered.splice(filtered.indexOf(filtered[i]), 1);
                        }
                    }
                }
            }
            alert('Return filtered items');
            return filtered;
        } else {
            alert('Original items ');
            return items;
        }
    };
});

So if works fine when i add tag but when i remove this tag i should get initial items list, but i get already filtered list.

So for instance originally i have a list of 5 items and when i click some tag I should get 4 items. But when I remove this tag i should get 5 items again, but i still get 4 items.

I think it is because in this line of code:

return function (items, filter) {

when filter invokes second time, items are already filtered and returned list before. Any ideas how can i fix it?

2
  • Sounds like a caching issue. What happens if you clear your cache in between runs? Commented Aug 4, 2015 at 13:33
  • You can use ngTagsInput module. It is very powerful and you can extend it with your needs. Just google it. Commented Aug 4, 2015 at 13:33

1 Answer 1

1

The problem is the synergy of the following 2 lines:

var filtered = items;
...
filtered.splice(...);

You see splice alters the array; but the array already points to the original items, meaning that the original items array is being altered!

The solution is to make a shallow copy of the array; instead of the first line above, do:

var filtered = items.slice(0);
Sign up to request clarification or add additional context in comments.

1 Comment

That's a good solution, but in my scope i will always have whole items array and on my view will be render filtered array, how can i check if filtered is empty to show user message about it? I guess i dont have any access to filtered variable, thanks in advance

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.