75

I am passing date value to my custom filter this way:

angular.module('myapp').
  filter('filterReceiptsForDate', function () {
    return function (input, date) {
      var out = _.filter(input, function (item) {
        return moment(item.value.created).format('YYYY-MM-DD') == date;
      });
      return out;
    }
  });

I would like to inject a couple of scope variables there too, like what I can do in directives. Is that possible to do this without having to passing these vars explicitly as function arguments?

Sergei Basharov
  • 51,276
  • 73
  • 200
  • 335

2 Answers2

126

Apparently you can.

Usually you would pass scope variables to the filter as function parameter:

function MyCtrl($scope){
  $scope.currentDate = new Date();
  $scope.dateFormat = 'short';
}
<span ng-controller="MyCtrl">{{currentDate | date:dateFormat}}</span> // --> 7/11/13 4:57 PM

But, to pass the current scope in, you'd have to pass this:

<span ng-controller="MyCtrl">{{currentDate | date:this}}</span>

and this will be a reference to current scope:

Simplified:

app.controller('AppController',
    function($scope) {
      $scope.var1 = 'This is some text.';
      $scope.var2 = 'And this is appended with custom filter.';
    }
  );
  

app.filter('filterReceiptsForDate', function () {
  return function (input, scope) {
    return input + ' <strong>' + scope.var2 + '</strong>';
  };
});
<div ng-bind-html-unsafe="var1 | filterReceiptsForDate:this"></div>
<!-- Results in: "This is some text. <strong>And this is appended with custom filter.</strong>" -->

PLUNKER

Warning:

  1. Be careful with this and use scope only to read the values inside the filter, because otherwise you will easily find your self in $digest loop.
  2. Filters that require such a "heavy" dependency (the whole scope) tend to be very difficult to test.
Community
  • 1
  • 1
Stewie
  • 60,366
  • 20
  • 146
  • 113
  • Thanks for the comprehensive answer. I suppose I'd better just pass those variables explicitly to the filter. – Sergei Basharov Jul 12 '13 at 07:08
  • Thanks! For others reading this, you don't have to use `ng-bind-html-unsafe` unless you are passing html. also, I used `$scope` instead of `scope` so it is the same inside the filter's function as I am used to everywhere else :) – Wade Nov 04 '16 at 20:49
  • If you really need to update a scope variable, then you should move your filter in the `Controller`. This way, it doesn't have a "heavy" dependency and is easier to test. Just use `$filter('filter')(array, expression, comparator, anyPropertyKey)` in the `Controller` – ghiscoding Feb 21 '17 at 18:23
5

I found that this references local $scope. Not sure if this is safe way of accessing it.

Himanshu Moradiya
  • 4,769
  • 4
  • 25
  • 49
pavel_karoukin
  • 286
  • 3
  • 10