In angularjs, What is the different between those 2 controllers - angularjs

I've seen 2 types of controllers definition:
angular.module('myApp.controllers',[])
.controller('MainCtrl', ['$scope'], function($scope){
//controller code
}
And a simple:
function MainCtrl($scope) {
//controller code
}
What's the different? Which one is the preferred one?

The difference is that the first is a controller inside the module.
The second method is a controller on the global ( on the Window object! ).
Like you would have heard already, polluting the global object is a bad idea. Hence, the second method is not preferred (But is used for quick prototyping to show off a feature easily and is easier to type. So this one is used in pretty much all examples.)
The first way, i.e
angular.module('myApp.controllers',[])
.controller('MainCtrl', ['$scope'], function($scope){
//controller code
}
is the preferred way and should be used in all for production applications.

Related

AngularJs, What is better when creating a controller?

What is better when creating a controller in AngularJs:
1-
angular.module('myApp')
.controller('MyController',['$scope','dependencies','myService', function($scope, dependencies, myService ) {
}]);
2-
angular.module('myApp')
.controller('MyController', function($scope, dependencies, myService ) {
});
Performance wise, the first is technically better, although that cost is probably negligible. If you do it the second way, angular literally calls the .toString() function on your controller function, and then parses the string to determine the dependencies. So you can either declare them yourself, or angular will parse your function as a string to determine them.
As a developer, I find it easier to read and write the second version. Just be aware that you have to change things to the first form if you plan on uglifying/minifying your code. Some tools will do this for you automatically (ngAnnotate, for example), so that you can write it the 2nd way, but have it deployed the first way.
With this method you have the advantage of function hoisting , function name for debugging , ability to mutate $inject;
also easier to reason about & debugging.
function myController(){
}
myController.$inject = ['$scope','dependencies','myService'];
angular.module('myApp' ,myController);

AngularJS controller: what is the right syntax?

I usually declare one controller this way:
.controller('myController', function($scope,/*other dependecies go here*/){
// controller definition
};
However in some examples (including one from AngularJS's official documentation) I found something like:
angular.module('controllerExample', [])
.controller('SettingsController2', ['$scope', SettingsController2]);
function SettingsController2($scope) {
// controller definition
};
or simply (which is equivalent, I guess):
angular.module('controllerExample', [])
.controller('SettingsController2', ['$scope', function(){
// controller definition
}
]);
Now, I don't understand what is the actual difference between snippet 1) and snippets 2) and 3)
Also, I don't understand why sometimes the same dependency is both outside the function definition and in function parameters (like snippet 3) ) but outside is without $ and inside is with (sorry I can't find an example now. But I'm sure I had this situation).
Thank you in advance
The array syntax is to prevent angular from breaking when the code goes through a minifier. If you are not minifying your javascript, there really isn't a big difference other than you get to type more/less. Angular reads in these functions as a string and processes them. Some minifiers screw that up, so that weird syntax is the current solution.
#jwimmer's answer is correct but I want to offer one more possibility. You can clean up the syntax a bit and keep your code minification safe using $inject.
someCtrl.$inject = ['$scope', 'someDependency'];
function someCtrl($scope, someDependency) {
...
}
angular.module('someApp')
.controller('someCtrl', someCtrl);

declare module for each file or use the app module for all files?

I started learning angularjs and I see 2 types of module uses and I cant understand when to use this and when this:
example1:
var app = angular.module('app', []);
app.factory('Comment', function($http) {
}
app.controller('mainController', function($scope, $http, Comment) {
}
or
example2:
angular.module('commentService', [])
.factory('Comment', function($http) {
}
angular.module('mainCtrl', [])
.controller('mainController', function($scope, $http, Comment) {
}
var app = angular.module('app', ['commentService','mainCtrl']);
sometimes I see module declarion in each file(services factory controllers and so on)
and sometimes I see using the app module in those files, what is the right way? and why both of them works?
First and foremost, if you're concerned about app organization, read the discussion on the yeoman-generator-angular issue board from about a year ago. There's way more wisdom there than you could feasibly expect to get in a SO answer.That said, I'll try to provide an answer that's more pertinent to your specific concern, and (marginally) more concise.
DO NOT make a module for a single controller like angular.module('MainCtrl',[]).controller('MainCtrl'), or even a set of controllers who are only related in that they are all controllers:
angular.module('appCtrl', [])
.controller('appleController', function ($scope) {})
.controller('orangeController', function ($scope) {})
.controller('unicornController', function ($scope) {})
;
Why is this a bad idea? First, by definition, it's categorical, not modular; modules are groupings of system components which are related topically, not conceptually. When you're building a car, you don't put in all of the nuts and bolts at once. You put in the nuts and bolts that hold together the module that you're building. Controllers are like nuts and bolts. An engine is like a module.
Second, now you have to inject the appCtrl module anywhere that you want access to a controller. That's just a mess for developers to have to deal with; they're always digging through the code trying to find "whatever that module with that one thing in it" was, or they'll just repeat code all over the place.
Dependency Injection in AngularJS is less a rule than a (clever and awesome) string manipulation hack, and JavaScript has no "namespacing" system in the classical sense. Creating modules like app.products or app.cart is more for the developer's convenience and/or controlling the release cycle than making the program "work".
For these and other reasons, I caution developers against "Premature Modularization". If you're writing something app-specific---that is, you won't be reusing it right now in another app---why not just attach it to your app module? Then you have access to it anywhere in your app that you want it. (There are of course complexities that might cause you to change this, but if/when those do arise that's when you modularize).
Structure your directories by feature (Angular conventions do condone BDD, after all):
|-app/
|-|-cart/
|-|-|-CartItemsModel.js
|-|-|-OrderRepository.js
|-|-|-cart.html
|-|-|-add-item-modal/
|-##some more cart stuff
|-|-checkout/
|-|-|-confirmation/
|-|-|-|-confirmation.html
|-|-|-|-confirmation.less
If you're writing feature files or getting acceptance criteria from your employer, you can even model your directory structure directly after those features or requirement sets. That makes everything smooth from defining the scope of an iteration through documentation through revisiting code at a later time.
Both example work. But for instance with the example 2, this syntax can be used for separation of concern. You may need a module that is responsible for providing services which gives you function for Rest calls. Or another module that package some directives.
It's generally considered good practice to segregate your modules into different files. This will ensure that you are practicing good code control, and gives your code a greater degree of portability and debug-ability. Instead of declaring modules in the same file, declare them in different files with their module name.
It's good practice to segregate your files based on their module-controller relationship -- that is, each controller should have its own file, like this:
\scripts\controllers\
- - main.js
- - comments.js
Then, inside your main.js file, you'll start off with the controller declaration:
//main.js
angular.module('app')
.controller('MainController', function ($scope, $http) {
// Controller-scope stuff here
});
Finally, inside your comments.js file:
angular.module('app')
.controller('CommentsController', function($scope, $http, $routeParams) {
// Comment controller code
});
One way to help with organization right off the bat is to organize your files is with a seed template, like Angular Seed.
Just remember that you want to keep your module('app').controller('whatever') inside whatever.js, and any other .factory('forWhatever') (like in your example) should be contained with that parent .controller('whatever') inside the whatever.js file.

What is the difference between passing a function and array as an AngularJS controller?

Both of these work, but what is the actual difference between each implementation? I'm sure there is a logical reasoning behind each method, and I wish to be enlightened.
angular.module('app').controller('GeneralCtrl',
function($scope, $location, exampleService) {
$scope.variable = exampleService.getExampleVariable();
}
);
angular.module('app').controller('GeneralCtrl',
['$scope', '$location', 'exampleService', function($scope, $location, exampleService) {
$scope.variable = exampleService.getExampleVariable();
}]
);
What is the actual difference between these? Where would you use them differently? Why?
Answer: Turns out the latter is minification safe as minifiers rename parameter names, so dependencies cannot be inferred from their names, and so must be annotated.
This is what Angular calls "inline notation" for dependency injection (see http://docs.angularjs.org/guide/di for a whole lot of detail).
In the example you gave, the ng-controller directive is actually doing the work behind the scenes, of hooking up $scope, $location, and exampleService into the variables you're providing to that first function. It's doing this by default based on variable names (that is, it assumes that a variable called $scope is asking for the $scope dependency).
That said, when you minify your code, the variable names get chopped down also (ie, $scope might become a). When that happens, Angular now doesn't know what you meant by the variables anymore.
One option is to add
GeneralCtl.$inject('$scope', '$location', 'exampleService')
Another is to provide those strings like you did in the second example. This makes sure that even if the variable names get changed around, you're telling Angular what they were supposed to represent, and it knows how to set them properly.

From two ways of Creating AngularJS Controllers which should be used and why?

In most demos below method is given
First Method:
function MyCtrl( $scope ){
$scope.someValue = "All your base are belong to us!";
}
Second Method:
app.controller("MyController",funciton( $scope ){
$scope.someValue = "All your base are belong to us!";
});
What are the pros and cons of using either method?
I'll try to give a quick summary each options pros and cons.
1) The following version is often used in examples around the web because it's easy to write. I wouldn't recommend it in real code however, for two reasons. First of all it can break horribly if you minify your code (and you should), secondly you are littering with globals which is generally bad form and encourages sloppy dependencies that are hard to test.
function MyCtrl( $scope ){
$scope.someValue = "All your base are belong to us!";
}
2) The second version you wrote is better. It contains the function on the app which is good, but it can still break from some minifiers.
app.controller("MyController",function( $scope ){
$scope.someValue = "All your base are belong to us!";
});
3) To make it better, lets do this instead. Note that the function is now inside a list with its dependencies. This "double" naming of the dependencies helps angular keep track of things in minified code.
app.controller("MyController", ['$scope', function( $scope ){
$scope.someValue = "All your base are belong to us!";
}]);
4) You can also inject your dependencies after your controller, something like this. This should also be safe from minifiers as far as I know (I haven't used this version myself).
app.controller("MyController",function( $scope ){
$scope.someValue = "All your base are belong to us!";
}).$inject = ['$scope'];
So 3 and 4 are the best ones. They survive minifying and they allow you to easily mock out any dependency when writing tests. As far as I know the difference between 3 and 4 is cosmetic so both should work equally fine. I personally use 3, I think it looks slightly nicer :)
I would highly recommend the second one.
The reason behind this is minification. Angular will try to match the controller's name you call in the templates via ng-controller, e.g.:
<div ng-controller="Controller">
<!-- [...] -->
</div>
Suppose you have a controller like this:
function Controller($scope) {};
and minify it (with some minifiers), you'll get an output like this:
function c(s) {};
Quick EDIT: I checked it with uglify - it will preserve your function name (and you'll be fine), I used a maven based minifier in a project of mine, which actually mangled the method names (I guess I have to replace it)
Your app might just break from that.
Therefore it is recommended to use strings as identifiers for controllers (and injections, etc.) like this:
var app = angular.module("module", []);
app.controller("Controller", ['$scope', function(scope) {
}]);
This will stop a minifier from breaking the app. The reason to put injections like this is as follows:
var app = angular.module('module',[]);
function Ctrl($scope, $location) {
$scope.test = 42;
};
will get minified to (by UglifyJS):
function Ctrl(a){a.test=2}var app=angular.module("module",[])
and Angular will not know that you need the $scope here.
If minification does not matter to you, you can use either one, as the question really just breaks down to maintainability and readability. Also, if you have multiple modules with controllers, the second one will not get you into trouble.
The difference is that the second version defines the controller in your app space. Thus the app.controller call. Difference is that afaik you can only use the controller inside of an ng-app="yourApp" instead of everywhere on the site.
Personally, I like more the 2nd method, because it is easier to review the code and it is more maintainable, those are just my thoughts.But with 1st method you can put it as a controller in other apps.
Here is what I found from
http://www.bennadel.com/blog/2421-Creating-AngularJS-Controllers-With-Instance-Methods.htm
In most AngularJS demos, you will see Controllers being defined as free-standing JavaScript functions:
function MyCtrl( $scope ){
$scope.someValue = "All your base are belong to us!";
}
These functions are then referenced in the View using the ngController directive:
<div ng-controller="MyCtrl">
{{ someValue }}
</div>
NOTE: You should never ever abbreviate "Controller" as "Ctrl". I am only doing that here because this it is what you will typically see in a demo. You should try to avoid abbreviations as much as humanly possible when naming things in programming.
The expression used to define the ngController directive is the name of the Controller in your dependency injection (DI) framework. In an AngularJS application, the dependency injection framework is provided directly by AngularJS. This means that, rather than using a free-standing function, we can use the AngularJS controller() method to define our Controllers:
// Define "MyController" for the Dependency Injection framework
// being used by our application.
app.controller(
"MyController",
funciton( $scope ){
$scope.someValue = "All your base are belong to us!";
}
);
Here, we are defining the controller as an identifier - MyController - and a constructor function. And, once we can do this, we can get much more fine-tuned in how we actually define our constructor function.

Resources