4

Sometimes I see dependency injection in Angular done like:

angular.module('controllers')
  .controller('BooksListCtrl', ['$scope', 'Books', function($scope, Books){
    Books.get(function(data){
      $scope.books = data;
    });
  }]);

And sometimes it looks like the following without the array, and just passing dependencies directly into the function:

angular.module('controllers')
  .controller('BooksListCtrl', function($scope, Books){
    Books.get(function(data){
      $scope.books = data;
    });
  });

Is one the right way? Does it depend on whether you are doing dependency injection on a controller vs directive vs etc?

1
  • there is also a third way which is via $inject. The second way on the question is not recommended because it breaks minification, see docs.angularjs.org/guide/di section Implicit Annotation Commented Jul 14, 2015 at 12:23

3 Answers 3

3

Sometimes I see dependency injection in Angular done like:

angular.module('controllers')
  .controller('BooksListCtrl', ['$scope', 'Books', function($scope, Books){
    Books.get(function(data){
      $scope.books = data;
    });
  }]);

And sometimes it looks like the following without the array, and just passing dependencies directly into the function:

angular.module('controllers')
  .controller('BooksListCtrl', function($scope, Books){
    Books.get(function(data){
      $scope.books = data;
    });
  });

which one is the right way ?

Both

Does it depend on whether you are doing dependency injection on a controller vs directive vs etc?

No

so how are they different ?

Well first form gives you the freedom to handle the dependencies with your own custom name. For example

app.controller('BooksListCtrl', ['$scope', 'Books', function($scope, myOwnBookName){
    myOwnBookName.get(function(data){
      $scope.books = data;
    });
}]);

while second one does not..but both are correct.

Also, you need to be a little cautious while using the first form because you might mistakenly skip a dependency and/or link it with the wrong one. For example doing something like:

app.controller('BooksListCtrl',['$scope','$window','$rootScope', function(foo, bar){
 ...
}]);

would be extremely damaging as foo will now point to $scope, bar will point to $window while $rootScope would be undefined. Just keep the order intact and follow proper naming convention.

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

3 Comments

You should also keep in mind that you need to use the [] syntax if you want to minify your application, as otherwise the variable names will change and angular can't resolve.
Exactly, using aVeryLongNameforServiceOrFactory.anyMethod(). everytime in will make things look ugly..specially if you dont own the service/factory to change its name
1

When you just pass dependency in function, it can not be obfuscated. While you pass an array with function replicating the same dependencies, you can obfuscate the code without breaking the flow

Angular most probably uses the toString method to read out the dependencies in a function passed. When you obfuscate, angular won't be able to read out the argument as dependencies. Now when you pass an array with function as last element using rest of element as arguement in the same order, angular uses array elements to identify the dependencies as they are values and won't be affected by obfuscation.

So as you have wrote in the comment, Yes! it does the same. like :

 ['$scope', '$location', function (s, l){}] ;

In this angular tries to read array element to inject dependencies not the argument of function.

1 Comment

Might you be able to give an example of obfuscation? Would it be ['$scope', 'Books', function(s, b){...}] where $scope and Books have been obfuscated to 's' and 'b'?
1

Prefer the first version you mentioned over the second:

angular.module('controllers')
  .controller('BooksListCtrl', ['$scope', 'Books', function($scope, Books){
    Books.get(function(data){
      $scope.books = data;
    });
  }]);

This version protects your code from being mangled during minification (even if you're not currently minifying your code you most likely will in the future). The second version you mentioned is perfectly legal, BUT when minified your dependencies such as $scope and Books may very well become a and b and your services obviously will never be injected.

There's also a second way to annotate your dependency injection:

angular.module('controllers')
  .controller('BooksListCtrl', BooksListCtrl);

BooksListCtrl.$inject = ['$scope', 'Books'];

function BooksListCtrl($scope, Books) {
  Books.get(function(data){
    $scope.books = data;
  });
}

This makes your dependency injection very clear, and again protects your code from minification mangling.

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.