32

Given a filter method that returns true if some condition is met, is it possible to invoke its opposite in HTML, e.g. to use:

"item in items | filter:!AllDay"

instead of

"item in items | filter:AllDay"

? Or do you have to maintain two separate filter methods (one for false and one for true)?

shacker
  • 14,712
  • 8
  • 89
  • 89

4 Answers4

59

As noted by ENDOH (this SO question is technically a duplicate), you can negate a filter by prepending '!' to the filter string, like this:

filter:'!'+myFilter

Note that the '!' is quoted. The documentation is not terribly clear on this, and an example there would be helpful.

Community
  • 1
  • 1
shacker
  • 14,712
  • 8
  • 89
  • 89
  • 3
    When myFilter is a method, not a model, this does not work on angular 1.0.7. The myFilter method is not called at all. – Denis Pshenov Jul 23 '13 at 12:01
  • Good pointer about the '!' being quoted - that stumped me for a few minutes (and looks obvious in hindsight) – Alexander Marquardt Dec 11 '14 at 05:06
  • 2
    this was very helpful, for property based filtering instead of strings, it took a bit of trial & error though to figure out: `filter:{myPropertyName:'!'+'EverythingOtherThanMe'}` – pulkitsinghal May 29 '15 at 00:52
  • 1
    if the value for myFilter is '2', it will block 2, 22, 202, 102, etc. I don't see how you can fix that without writing a function. – Daniel Baughman Jul 05 '16 at 21:58
  • @shacker , check this fiddle `http://jsfiddle.net/U3pVM/33383/` , why last one is not display in list, event last one id is -12 not -1 ?? – chirag satapara Jul 18 '17 at 06:08
32

shacker's answer didn't work for angular 1.0.7, so here's another way to do this:

// You can register this in your AppCtrl if you like, otherwise just use $scope.
$rootScope.not = function(func) {
    return function (item) { 
        return !func(item); 
    }
};

Then you would do this:

filter:not(myFilterMethod)
Denis Pshenov
  • 11,157
  • 6
  • 42
  • 42
24
filter:({day: '!'+AllDay.day})
Muhammed Basil
  • 1,834
  • 1
  • 21
  • 39
  • 1
    I read on another SO post that this syntax also works: filter:!{day:AllDay.day} But it didn't for me. This was the only way that worked. – mrjrdnthms Jul 20 '15 at 21:58
0

Another option is to create a new negation filter and pipe it:

  .filter('not', function() {
    return function(input) {
      return !input;
    }
  })
"item in items | filter:AllDay | filter:not"
Janne Annala
  • 25,928
  • 8
  • 31
  • 41