Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to disable auto-injector (magic discovery of injector types) in angularjs?

Tags:

angularjs

Angularjs has this nice feature of auto discovery of the providers based on a function arguments. For example, if I want to use $http in some function i would call it like that:

$inject.invoke(function ($http) {

});

Angularjs will "know" what are my dependencies. It will figure it out by reading my function's body and based on argument names it will know.

However there is a problem when you would like to minify your code. Minifier will change arguments names. That's why we should use this notation:

$inject.invoke(['$http', function ($http) {}]);

or this notation:

function Foo ($http) {}
Foo.$inject = ['$http'];

$inject.invoke(Foo);

We should always in the end minify our code. So we should avoid using this magic (first example) notation.

And now my problem:

I'm trying to minify my js code and angularjs cannot resolve a provider name. I can't find a place where i haven't specified .$inject = [...]. Now it just says: "Unknown provider a" and i don't know what function is it referring to.

Is it possible to turn off angularjs auto discover (auto-injector) of providers? I would test and repair my code before minifying.

So, I'm wondering how to disable this "magic" angularjs deduction. Since I always minify my code I want angularjs to yell at me when I will accidentally use this superheroic evil.

How to turn it off?

like image 480
Szymon Wygnański Avatar asked Nov 01 '12 11:11

Szymon Wygnański


People also ask

What is $inject in AngularJS?

$injector is used to retrieve object instances as defined by provider, instantiate types, invoke methods, and load modules. The following always holds true: var $injector = angular.

Does AngularJS support dependency injection?

Dependency Injection is pervasive throughout AngularJS. You can use it when defining components or when providing run and config blocks for a module.

When an AngularJS application is bootstrapped how many objects are created by injector?

Injector is created inside this bootstrap() . boostrap() internally calls createInjector() to create the injector. There are two injectors. Only 1 is exposed for angular developers to use.

What is not recommended in AngularJS?

It is tempting to do too much work in the AngularJS controller. After all, the controller is where the view first has access to JavaScript via $scope functions. However, doing this will cause you to miss out on code sharing across the site and is not recommended by AngularJS documentation.


2 Answers

Just edit the source. Find 'function annotate', and replace the fn == 'function' block with something like this:

if (typeof fn == 'function') {
  console.log("Bad magic injection in "+fn.toString().replace(STRIP_COMMENTS, ''));
}
like image 80
Andrew Joslin Avatar answered Oct 21 '22 18:10

Andrew Joslin


update:

If anyone needs this because of trying to minify, maybe here is another possible solution

ngmin. It is an AngularJS application minifier project.

Not sure if this help.

According to Igor Minar,

You should make something like this

factory('Phone', function($resource){ ... }))

to

factory('Phone', ['$resource', function($resource){ ... })])

Here is the official doc from Dev guide.

$inject Annotation

To allow the minifers to rename the function parameters and still be able to inject right services the function needs to be annotate with the $inject property. The $inject property is an array of service names to inject.

var MyController = function(renamed$scope, renamedGreeter) {
...
}
MyController.$inject = ['$scope', 'greeter'];

Care must be taken that the $inject annotation is kept in sync with the actual arguments in the function declaration.

This method of annotation is useful for controller declarations since it assigns the annotation information with the function

like image 29
maxisam Avatar answered Oct 21 '22 17:10

maxisam