3

I've been doing some work with angular lately, and I noticed that one can omit the array of names for the dependencies in controller functions. If you do this, the controller still works correctly and dependencies get injected just fine.

I'm sure I'm missing something. What is the reason for those names?

2 Answers 2

5

See paragraph a "Note on Minification" in https://docs.angularjs.org/tutorial/step_05

It is used to keep a string reference of your injections of dependencies after minifications :

Since Angular infers the controller's dependencies from the names of arguments to the controller's constructor function, if you were to minify the JavaScript code for PhoneListCtrl controller, all of its function arguments would be minified as well, and the dependency injector would not be able to identify services correctly.

Sign up to request clarification or add additional context in comments.

3 Comments

Ha! I knew I was missing something. Does that also mean I should not list my own factories in that array? Since their names will be changed.
I can add, that you should either : 1) always use this double notation or 2) use a tool that automatically adds it for you like github.com/alexgorbatchev/grunt-angular-injector because you surely will need minifuication at some point ;)
@CarlosBlanco To answer your question: yes you muwt use the double notation for either angular core dependencies or yours. After minification the variable name will be minified but it will point to the good dependency thanks to the "string" notation
1

Controllers are callables, and their arguments must be injected with existing/valid/registered dependencies. Angular takes three ways:

  1. If the passed controller (this also applies to providers) is an array, the last item is the controller, and the former items are expected to be strings with the names of dependencies to inject. The names count and the arity must match.

    //parameter names are what I want.
    c = mymodule.controller('MyController', ['$scope', '$http', function($s, $h) {}]);
    
  2. Otherwise, if the passed controller has an $inject property, it is expected that such property is an array of strings being the names of the dependencies. The length of the array and the arity must match.

    con = function($s, $h) {};
    con.$inject = ['$scope', '$http'];
    c = mymodule.controller('MyController', conn);
    
  3. Otherwise, the array of names to inject is taken from the parameter list, so they must be named accordingly.

    c = mymodule.controller('MyController', function($scope, $http) {});
    //one type, one minification, and you're screwed
    

You should never expect that the controller works if you don't explicitly set -explicitly- the names of the dependencies to inject. It is a bad practice because:

  1. The parameter names will change if you minify (and you will -some day- minify your script).
  2. A typo in your parameter name, and you'll be hours looking for the error.

Suggestion: always use an explicit notation (way 1 or 2).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.