stinaq
stinaq

Reputation: 1284

AngularJS 1.x custom filter can't be injected, unknown provider

I'm trying to create a custom filter, but when I try to inject it into my controller, I get an 'Unknown provider' error. I have checked and double checked all the references, but I can't see what's wrong.

I know that the file is referenced in my index.html correctly, it is loaded and can be found by the inspector. This is the code I have:

In my app.js:

angular.module('equiclass', ['equiclass.controllers',
                         'equiclass.services',
                         'ngRoute'])
.config(function ($routeProvider) {
$routeProvider
  .when('/courses', {
    templateUrl: 'views/courses.html',
    controller: 'CourseCtrl'
  // And some other stuff with routes
});

angular.module('equiclass.controllers', ['equiclass.services', 'equiclass.filters']);
angular.module('equiclass.services', []);
angular.module('equiclass.filters', []);

My filter:

angular.module('equiclass.filters')
  .filter('testFilter', function() {
    return function(input) {
      return undefined;
    };
});

And the controller:

angular.module('equiclass.controllers')
  .controller('CourseCtrl', function ($scope, testFilter) {

  });

Of course this is quite simplified, but it just doesn't work, and I can't see why. I have made several services and they all work and play along nicely.

Upvotes: 11

Views: 36451

Answers (4)

seangwright
seangwright

Reputation: 18205

You don't need to inject the filter itself.

This code...

angular.module('equiclass.controllers')
  .controller('CourseCtrl', function ($scope, testFilter) {

  });

Should be

angular.module('equiclass.controllers')
  .controller('CourseCtrl', function ($scope) {

  });

And inside CourseCtrl you should use your filter as you normally do.

Injecting the module 'equiclass.filters' into your module 'equiclass.controllers' is enough.

I had a similar issue and made a post about it on my blog.

--Edit

As n00dl3 mentions below the tricky part is how the auto-naming convention works in Angular. If you name your filter specialNumberFilter then when you inject it you need to refer to it as specialNumberFilterFilter. This allows you to use the filter as a function, which is what it is.

// In a controller vm.data = specialNumberFilterFilter(vm.data, 'a');

But I believe you can also use the filter without injecting it into a controller if it is used in a string expression that is being evaluated by, say, a watch because this would be the same as the scenario when you are using it in a template.

// Inside a watch - no controller injection required `$scope.$watch('vm.data | specialNumberFilter', function(new, old) { ... })`

Upvotes: 9

n00dl3
n00dl3

Reputation: 21564

According to Angular's documentation :

if you want to use your filter in a template

then you just need to inject it in your module and then use it like this {{ expression | filter }} or {{ expression | filter:argument1:argument2:... }} .

doc

if you want to use your filter in a controller, directive, and stuffs :

inject a dependency with the name <filterName>Filter, like this :

controller('MyController', ['filterFilter', function(filterFilter) {}]);

doc

so for this particular case :

angular.module('equiclass.controllers')
  .controller('CourseCtrl', function ($scope, testFilterFilter) {

  });

Upvotes: 5

Nuriel
Nuriel

Reputation: 3741

you didn't mention if it's in production or on a local server, but just in case you are minifying your files, try this:

angular.module('equiclass.controllers')
  .controller('CourseCtrl', ['$scope', 'testFilter', function ($scope, testFilter) {

  }]);

Upvotes: 2

BKM
BKM

Reputation: 7079

If you want to use filter inside a controller you have to inject $filter attribute to your controller and can access it like

$filter('filtername');

You can use like

function myCtrl($scope, $filter)
{
    $filter('filtername')(arg1,arg2);
}

Upvotes: 15

Related Questions