0

I'm starting with AngularJS and I have some problems because I found on the internet a lot of examples about how declare the code, but generally the code is different.

For example on the controller:

(function(){
  angular.module('myApp')
    .controller('myCtrl', myCtrl);

  function myCtrl($scope, Restangular, myFactory) {
     /* Code here */
  }
)();

In other pages I found this way:

var myApp = angular.module('myApp');
myApp.controller('myCtrl', myCtrl);
myCtrl.$inject = [$scope,Restangular, myFactory];
function myCtrl($scope, Restangular, myFactory) {
  /* Code here */
}

And, not being enough .. I found this other way:

var myApp = angular.module('myApp');
myApp.controller('myCtrl', function($scope, Restangular, myFactory) {
  /*Code here*/
});

I'm a little confusing and I don't know what is the best way to declare my components (controllers, factory, constants etc...)

Thanks for advance.

3
  • 1
    Your second way should be myCtrl.$inject = ['$scope','Restangular', 'myFactory']; Commented Aug 17, 2014 at 17:44
  • I generally prefer to use second (corrected_^^_) way Commented Aug 17, 2014 at 17:45
  • runTarm u alright, I typed wrong. PSL, why I should use myCtrl.$inject...? Is not enough with put that on: function myCtrl($scope, Restangular ....) ? Commented Aug 17, 2014 at 17:47

2 Answers 2

2

What matters is to understand the similarities and differences between all these ways of doing. Then you'll use the technique that you prefer.

Let's examine the first one:

(function(){
  angular.module('myApp')
    .controller('myCtrl', myCtrl);

  function myCtrl($scope, Restangular, myFactory) {
     /* Code here */
  }
)();

First of all, it does everything inside a self-called anonymous function. The reason for using this JavaScript trick is to be able to declare functions without polluting the global namespace, and thus having myCtrl being a global function accessible from everywhere, and potentially conflicting with another global function.

Inside the anonymous function, a function named myCtrl is defined. angular.module('myApp') asks angular to return a reference to a previously defined module, and the controller function is added as a controller to the returned module. It's equivalent to

var myApp = angular.module('myApp');
myApp.controller('myCtrl', myCtrl);

except it doesn't need a variable.

This technique has a drawback: it won't support minification, for the reason described in the section "A Note on minification" of https://docs.angularjs.org/tutorial/step_05, unless a preprocessing tool like ngAnnotate is used to transform this code to minifiable code.

Let's now look at the second one:

var myApp = angular.module('myApp');
myApp.controller('myCtrl', myCtrl);
myCtrl.$inject = ['$scope','Restangular', 'myFactory'];
function myCtrl($scope, Restangular, myFactory) {
  /* Code here */
}

Here, a global variable myApp is defined. That's bad. A global function myCtrl is also defined. Thanks to the use of $inject, this code will support minification, though.

Let's look at the last one:

var myApp = angular.module('myApp');
myApp.controller('myCtrl', function($scope, Restangular, myFactory) {
  /*Code here*/
});

Here again, a global variable myApp is defined. The controller function is now defined as an anonymous inline function. This avoids defining a global function. This code, once again, is not minifiable.

My advice: if you don't use ngAnnotate, use the following:

angular.module('myApp').controller('MyCtrl', ['$scope', 'Restangular', 'myFactory', function($scope, Restangular, myFactory) {
   ...
}]);

It doesn't need a self-calling anonymous function, supports minification, and doesn't define any global variable or function.

If you use ngAnnotate, the above code can be simplified to

angular.module('myApp').controller('MyCtrl', function($scope, Restangular, myFactory) {
   ...
});

And finally, if you really want your controller function to have a name (for debugging purposes, for example, although I've never needed it):

angular.module('myApp').controller('MyCtrl', ['$scope', 'Restangular', 'myFactory', function MyCtrl($scope, Restangular, myFactory) {
   ...
}]);

or, with ngAnnotate:

angular.module('myApp').controller('MyCtrl', function MyCtrl($scope, Restangular, myFactory) {
   ...
});
Sign up to request clarification or add additional context in comments.

3 Comments

Great explanation! I also encourage the use of ng-annotate as it will prevent a silly dependencies/parameters mismatch.
Great explanation JB Nizet. You really has helped me a lot with this. I have on small doubt, is necessary use 'use strict' on my code? I really don't understand how that's works and when I need to use that. Thanks for advance again Nizet.
No, it's not necessary. To be frank, I'm not really sure how it works, especially if strict and non-strict scripts end up being concatenated in the same JS file.
0

You only need to declare your dependancies twice, if you use a minifier. In most cases the third way will be fine.

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.