Angularjs custom filter and dependency injection

Aviel Fedida picture Aviel Fedida · Jan 11, 2014 · Viewed 27.6k times · Source

I'm new to AngularJS and i see this syntax a lot:

function someFunc(){
   return function(input){
    return 'hello' + input;
  }
}

The function above is a general syntax i tend to see a lot but problem is specific with this example for custom filter:

angular.module('bookFilters', [])
    .filter('newBookFilter', function(){
          return function(input){
        return 'The Book: ' + input.name + 'is new !';
   };
});

I understand that wrapping the function with another function gives me an opportunity to use dependency injection, Here is my questions about it:

Does the filter get the function returned from the wrapping function? Then is it able to use dependency injection to inject the value into the function? Theoretically that:

This code:

{{bookObj | newBookFilter}}

Will become:

{{   bookObj | function(input){return 'The Book: ' + input.name + 'is new !'; }  }}

And finally the {{}} will return the final value from the function.

Why can't i just inject the input to the first function like:

angular.module('bookFilters', [])
         .filter('newBookFilter', function(input){
             return 'The Book: ' + input.name + 'is new !';
     });

Why dependency injection will only work on returned function?

I know i really confused here, If anyone can help me i will be very thankful, Thank you all and have a nice day.

Answer

Vasiliy Kevroletin picture Vasiliy Kevroletin · Jan 11, 2014

The answer is opposite to your question. Angular injects only into factory function but not into resulting function:

   .filter('newBookFilter', function($log, ...){ // <- factory function
       return function(input, ...){              // <- resulting function
       };
   })

Factory function have arbitrary injected parameters. Resulting function have fixed parameters.

Second reason is that you can do some initialization in factory function. This is useful for example when you define new directive. Also factory returns closure which can capture variables and arguments from factory function. See example below. It uses dependency injection to get logging object. Here is full example.

  .filter('joinBy', function ($log) {     // <- injected here
    return function (input, delimiter) {  // <- used here
      var res = (input || []).join(delimiter || ',');
      $log.info(res);
      return res;
    };
  });