107

I'm reading http://www.alexrothenberg.com/2013/02/11/the-magic-behind-angularjs-dependency-injection.html and it turned out that angularjs dependency injection has problems if you minify your javascript so I'm wondering if instead of

var MyController = function($scope, $http) {
    $http.get('https://api.github.com/repos/angular/angular.js/commits')
      .then(function(response) {
        $scope.commits = response.data
      })
  }

you should use

var MyController = ['$scope', '$http', function($scope, $http) {
  $http.get('https://api.github.com/repos/angular/angular.js/commits')
    .then(function(response) {
      $scope.commits = response.data
    })
}]

all in all I thought the second snippet was for the old version of angularjs but ....

Should I always use the inject way (the second one) ?

0

7 Answers 7

106

Yes, always! So this way even if your minifer converts $scope to variable a and $http to variable b, their identity is still preserved in the strings.

See this page of AngularJS docs, scroll down to A Note on Minification.

UPDATE

Alternatively, you can use ng-annotate npm package in your build process to avoid this verbosity.

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

5 Comments

This, and some other issues are very good explained at egghead.io. JFYI
@Sprottenwels: Yup! Lot of useful resources there.
Instead of using this more verbose syntax you can use ngmin and a build tool (like Grunt) before you run minification. That way you can minify properly but also use either dependency injection syntax.
A note on minification have been moved here docs.angularjs.org/tutorial/step_07
37

It is safer to use the second variant but it is also possible to use the first variant safely with ngmin.

UPDATE:
Now ng-annotate becomes a new default tool to solve this issue.

Comments

8

Yes, you need to use explicit dependency injection (second variant). But since Angular 1.3.1 you can turn off implicit dependency injection, it's really helpful to solve potential problems with renaming at once (before minification).

Turning off implicit DI, using strictDi config property:

angular.bootstrap(document, ['myApp'], {
    strictDi: true
});

Turning off implicit DI, using ng-strict-di directive:

<html ng-app="myApp" ng-strict-di>

Comments

7

Just to point out that if you use

Yeoman

there is no need to do like

var MyController = ['$scope', '$http', function($scope, $http) {
  $http.get('https://api.github.com/repos/angular/angular.js/commits')
    .then(function(response) {
      $scope.commits = response.data
    })
}]

because grunt during minify take into account how to manage DI.

Comments

1

Like OZ_ said, Use ngmin to minify all angular js file, like directive.js service.js. After that you can use Closure compiler to optimize it.

ref:

How to minify angularjs scripts

Build with YO

Comments

0

You might want to use $inject as it mentioned here:

MyController.$inject = ['$scope', '$http'];

function MyController($scope, $http) {
  $http.get('https://api.github.com/repos/angular/angular.js/commits')
    .then(function(response) {
      $scope.commits = response.data
    })
}

Comments

0

Use Strict Dependency Injection to Diagnose Problems

With Implicit Annotation, code will break when minified.

From the Docs:

Implicit Annotation

Careful: If you plan to minify your code, your service names will get renamed and break your app.

You can add an ng-strict-di directive on the same element as ng-app to opt into strict DI mode.

<body ng-app="myApp" ng-strict-di>

Strict mode throws an error whenever a service tries to use implicit annotations.

This can be useful to determining finding problems.

For more information, see

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.