lostintranslation
lostintranslation

Reputation: 24573

Function used to filter in AngularJS 1.7 doesn't have "this" context

I am in the process of swapping out some controllers to components. I have a controller that has a custom filter function:

function MyController($scope, $filter) {
  $scope.customFilter = function(item) {
     $filter('filter')([item], $scope.search);
  }
}

in my template:

<input type="text" ng-model="search">
<div ng-repeat="item in (filtered = (items | filter:customFilter))" >

This works great when I have access to $scope. My filter function is much more complex, but a one off. I don't really need to define it as a true filter for the app as its not used anywhere else. Hence just a custom function in the controller itself.

However I am moving my controller over to component and don't have access to $scope.

class MyComponent {
  constructor($filter) {
    this.$filter = $filter;
    this.search = '';
  }
  customFilter(item) {
     this.$filter('filter')([item], this.search);
  }
  onCustomClick() {
    // if this is called from ng-click
    // I can access 'this' here, why not in filter
  }  
}

Template:

<input type="text" ng-model="$ctrl.search">
<div ng-repeat="item in ($ctrl.filtered = (items | filter:$ctrl.customFilter))">

The customFilter function is called as before, however it has no context bound. The 'this' variable is undefined. Am I doing something wrong, or should I be able to access the context of my component in the filter function?

If I call a function in ng-click the 'this' context is bound correctly, is this a limitation of calling a function of the component to filter?

Upvotes: 0

Views: 112

Answers (1)

FarukT
FarukT

Reputation: 1668

I am not sure but I think when filter calls your function it creates own context and for this reason you have a this of undefined.

A fast and alternative solution can be this sample, you can also pass parameters to filter function you defined and it will return an anonymous function

class MyComponent {
    constructor() {
      this.search = '';
    }
    customFilter(searchText) {
        return function (item) {
            $filter('filter')([item], searchText);
        }
    }
    onCustomClick() {
      // if this is called from ng-click
      // I can access 'this' here, why not in filter
    }  
  }

Template:

<input type="text" ng-model="$ctrl.search">
<div ng-repeat="item in ($ctrl.filtered = (items | filter:$ctrl.customFilter($ctrl.search)))">

Upvotes: 0

Related Questions