0

I am trying to filter through multiple properties in Angular. I am able to filter through one property easily by using an angular filter:{ title: searchString } but to filter through a multiple properties... i created my own custom filter which tries to match the search string by any of the properties in the array.

What I need to do is:

If John Wayne is passed through.. it shows John Wayne but if only John or only Wayne is passed through... It still shows John Wayne. Similarly for n w since John ends with an n and subTitle starts with a w

PS: I can only have one ng-model

HTML:

<input type="text" ng-model="searchString">

<div ng-repeat="tel in arr1 | customFilter: searchString:['title','subTitle']"></div>

JS:

$scope.arr1 = [
    {title: 'John', subTitle:'Wayne'}
    {title: 'Barry'}
];

.filter('customFilter',[ function() {
    return function(items, searchText, attrs) {
        var filtered = [];
        var filteredItems = items.map(function(item) {
            angular.forEach(attrs, function(attr) {
                if (item.hasOwnProperty(attr)) {
                    filtered.push(item);
                }
            });
        });
        return filtered;
  };
}])

My issue is that I am getting an error saying:

Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys. Repeater: tel in arr1

5
  • You have an error in the name of your filter: customFilter in your filter name and custommFilter in your html Commented Jan 5, 2017 at 17:01
  • @ManuelObregozo whoops.. that was a typo. Accidentally inserted that in the post but thats not the issue Commented Jan 5, 2017 at 17:03
  • I still do get what it the idea of the filter, what is the output, of your array? Commented Jan 5, 2017 at 17:18
  • @ManuelObregozo basically... whatever is typed in the search field... i want it to be matched against all properties of the array Commented Jan 5, 2017 at 17:20
  • I think i got it, let me put all together in a plunkr Commented Jan 5, 2017 at 17:21

2 Answers 2

1

I just made a few updates to your custom filter:

app.filter('customFilter',[ function() {
    return function(items, searchText, attrs) {
        var filtered = []; 
        for (var i in items){
          var keepGoing = true;
          angular.forEach(attrs, function(attr) {
            console.log(items[i][attr])
                if (items[i].hasOwnProperty(attr) && items[i][attr].includes(searchText)  && keepGoing) {
                    filtered.push(items[i]);
                    keepGoing=false;
                }
            });
        }

        return filtered;
  };
}])

Take into account that in this case it is case-sensitive.

Although it is working as expected, I feel like it can be improved.

Plunker Sample: https://plnkr.co/edit/YnkSSOpG8sBQvVChIIuP?p=preview

Sign up to request clarification or add additional context in comments.

4 Comments

I tried that before as well :(... but in your example it doesn't work when i type "wayne"
which is what led me to creating a custom filter
the match condition could be a substring aswell?
plnkr.co/edit/YnkSSOpG8sBQvVChIIuP?p=preview seems to be working as expected, please check. take into account that it is case-sensitive. If you do not want it to be like that, just transform the item to lower case. hope it helps
1

You are getting this error because of duplicates in the arr1. Just add track by $index to achieve the desired solution

<div ng-repeat="tel in arr1 track by $index | custommFilter: searchString:['title','subTitle']"></div>

2 Comments

error is gone when i insert track by at the end... but now it doesn't do what i want it to do... it doesn't filter correctly
filter either with title or sub title at a time. How can you do with both at a time?

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.