5

I've been cleaning up an external JSON URL feed that I am using, and I have successfully removed unnecessary special characters via a filter as so:

angularJS.filter('removeChar', function(){
    return function(text) {
        text = text.replace(/\[[^\]]+\]/g, ''); // Characters inside Brackets
        return text.replace(/\;.*/, ''); // Characters after Colon
    };
});

<span ng-bind-html-unsafe="item | removeChar">{{item}}</span>

However, what I am trying to achieve now - is to remove an ng-repeat item if it contains a specific string via a filter I can use.

For example:

<div ng-repeat="item in items | removeItem">{{item['flowers']}}</div>

If the item contains the word 'Red' or 'Green'

<div>Blue Roses</div>
<div>Red Roses</div>
<div>Orand and Green Roses</div>
<div>Yellow Roses</div>
<div>Red and Green Roses</div>

Only this will display from the ng-repeat with the filter:

<div>Blue Roses</div>
<div>Yellow Roses</div>

Help with an example would greatly be appreciated.

Thanks! Roc.

2 Answers 2

16

You can use a filter along with the ! predicate that negates the search string:

div ng-repeat="item in items | filter:'!Red' | filter: '!Green'">{{item['flowers']}}</div>

So filter:'!Red' removes anything that does have the string "Red" in it. Those results are passéd to filter: '!Green' which removes any results that have the string "Green" in them.

Here's the relevant docs: http://docs.angularjs.org/api/ng.filter:filter

Performance Update

I was curious about the cost of filtering so I did this jsperf: http://jsperf.com/angular-ng-repeat-test1/2

I created 1,000 strings (items) and then did 4 tests with the following results on my system:

1) Display all 1000 using DI 281,599 ops/sec

  {{items}}

2) Display all 1000 using ng-repeat (no-filter): 209,946 ops/sec 16% slower

  <div ng-repeat="item in items"> {{item}}</div>

3) ng-repeat with one filter 165,280 ops/sec 34% slower

  <div ng-repeat="item in items | filter:filterString1"> {{item}}</div>

4) ng-repeat with two filters 165,553, ops/sec 38% slower

  <div ng-repeat="item in items | filter:filterString1 | filter:filterString2"> {{item}}</div>

This is certainly not a scientific test- I didn't do any controls and it's possible for things like caching to have influenced the results. But I think the relative performance is interesting.

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

2 Comments

Thanks Dave! Exactly what I was looking for. Two questions: 1) Do you see any performance impact if the filtered content is less than 300 objects? Most likely 100 or less? 2) How difficult would it be to place all of the predicates into one .filter function? Thank you again Dave!
While certainly more items does have a performance impact. I think you should be fine with 300. I've seen numbers float around about 2,000 being where issues creep in. But that's anecdotal. If you really want solid numbers you could always toss the code into jsperf.com and compare with vs without filtering. 2) It's easy do multiple or tests in one filter. But you need to and them. So I'd write my own. They're easy: docs.angularjs.org/tutorial/step_09 And looks like Daniel has posted an approach to that.
7

You can use any function available in the current scope as the argument of filter. So you could write something like this, for example.

HTML:

<div ng-app="" ng-controller="FooCtrl">
    <ul>
        <li ng-repeat="item in items | filter:myFilter">
            {{item}}
        </li>
    </ul>
</div>

JS:

function FooCtrl($scope) {
    $scope.items = ["foo bar", "baz tux", "hoge hoge"];

    $scope.myFilter = function(text) {
        var wordsToFilter = ["foo", "hoge"];
        for (var i = 0; i < wordsToFilter.length; i++) {
            if (text.indexOf(wordsToFilter[i]) !== -1) {
                return false;
            }
        }
        return true;
    };
}

Here is a working Fiddle. http://jsfiddle.net/2tpb3/

Comments

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.