AngularJS boiler plate syntax - angularjs

One of the frustrations I face with AngularJS is the variety of styles that are used in examples. I have seen 4 different ways to declare and add AngularJS elements to a module (including different ways to declare the module). In another question I asked about using a global variable vs. directly declaring the module. Now I would like to know what are the advantages/disadvantages to using various styles to add elements to the module. (I will not include the examples that declare a global variable for the module, as that style has been discounted as a 'bad practice')
Assume the module is declared in file myMod.js as:
angular.module('myMod', [
// Angular modules
'ui.router'
,'ui.bootstrap'
,'ngResource'
,'ngStorage'
]);
Now I want to add a controller to the module, I have seen:
(assume each example represents the entire contents of a file named: myController.js)
option A:
angular.module('myMod')
.controller.('thisController',['dependencyA','dependencyB',
function(dependencyA, dependencyB){
....stuff to do
}]);
option B: just adding 'use strict'
'use strict';
angular.module('myMod')
.controller.('thisController',['dependencyA','dependencyB',
function(dependencyA, dependencyB){
....stuff to do
}]);
options C: wrapping the whole thing in an anonymous function as:
(function(){
'use strict';
angular.module('myMod')
.controller.('thisController',['dependencyA','dependencyB',
function(dependencyA, dependencyB){
....stuff to do
}]);
option D: Declaring a named function rather than an anonymous function in the controller declaration as:
(function(){
'use strict'
angular
.module('myMod')
.controller('thisController',thisController);
thisController.$inject = ['dependencyA','dependencyB'];
function thisController(dependencyA,dependencyB){
...stuff to do
}
Similar diverse examples exist for adding factories, services, directives, etc. into a module. As best I can tell these are different styles for accomplishing the same goal. Which techniques represent 'best practices' and 'why'?
(I am not wanting this to turn into an 'opinion piece' please offer 'objective' reasons to select a style.)

As for 'use strict', this has nothing to do with AngularjJS per se. It is a Javascript directive that enforces strict mode which prohibits the use of undeclared variables in Javascript.
Immediately-Invoked Function Expression (IIFE) that wrap angular code prevent the leaking of variables into the global scope.
As for declaring a named function, in my opinion this leads to much clearer code and is my preferred way.

They all perform the same job, I personally use the named function approach. But you can combine them if you want.
angular
.module('myMod')
.controller('thisController',['dependencyA', thisController]);
thisController.$inject = ['dependencyB'];
function thisController(dependencyA,dependencyB){
...stuff to do
}
I use TypeScript so my controllers look something like this.
export class thisController
{
static $inject = ['DependencyA'];
constructor(private _dependencyA: DependencyA)
{
}
}
angular.module('myMod').controller('thisController', thisController)

Related

Understanding syntax in Angular

I have been coding in Angular for a little bit of time now and I have created Modules, Controller and Services so far but I recently just came across a piece of code which I am just not able to understand. It is someone else's code and I think author has tried to define a service but not like I have created. Normally when I create a service it looks like below:
app.factory('portabilityService', [
'$resource', '$state', '$rootScope', function ($resource, $state, $rootScope) {
return { //definition };
}
]);
To me it is simple specify service name as the first argument inside Factory followed by all the dependencies and there you go.
Now, I came across some other code which looks like following:
(function () {
/*
* Manages which samples have been selected
*/
'use strict';
angular.module('maintenance.portability.module')
.factory('selectedSamplesSvc', service);
service.$inject = [];
function service()
{
//other function definitions
};
})();
Now, this raises a lot of questions:
First of all, is this really a service?
If yes, what is service.$inject = []?
Where should I add the dependencies?
What is the purpose of the constructor service() here?
Is it just a different way to create a service or there is a specific reason why we should define a service in this particular way?
I'll try to address your questions in order:
First, yes, this is definitely a way to declare a service. It's not entirely far off from what you are normally used to using.
The normal syntax for declarations in angular is:
typeOfDeclaration('stringNameOfDeclaration', functionDeclaration);
function functionDeclaration(){..};
In JavaScript, a function is an object, so an anonymous function can be used in place of the functionDeclaration, for example:
typeOfDeclaration('stringNameOfDeclaration', function(){..});
This inline declaration is usually easier to write when you are only making a single declaration, and is the defacto standard for most tutorial examples.
Note that these rules apply to all angular components (providers, filters, directives, controllers, etc.)
By declaring the function as a separate object rather than inline, the declaration and the function are more easily managed. You could, in theory, put the function itself into a different file (though this is not common). Also, if you are declaring multiple functions, this syntax allows you to group the declarations together and the functions together, which is mostly a matter of preference and coding style.
The optional array of dependencies in your example are a way to manage Dependency Injection in cases where the code will be minified. In this case, another alternate DI method is used, service.$inject = [];. This array can be used instead of the inline array, i.e. service.$inject = ['$resource', '$state', '$rootScope']; Again, this gives you a way to group your declarations in one place, your dependencies in another.
All the answers boil down to this: They're equivalent with equivalent definitions of the function passed to .factory.
Yes, it's a service (based on the prior statement)
$inject is an alternative to your [ names..., function(dependencies...) {...}] syntax
The same way just now your function definition is separate.
It's the function you pass anonymously
It's preference for the most part but explicit $inject is beneficial for minimizing
For additional considerations on the matter (in part) and overall good reading give this style guide a look.

Defining a controller - angularjs

I am doing it this way.
Method 1:
var app = angular.module('MyModule', ['ngDialog']);
app.controller('MyController', function ($scope,ngDialog) {
///
});
but i see a lot like the below kind in articles
Method 2:
app.controller('MyController', ['$scope', function ($scope) {
///
}]);
Please help me understand why is $scope mentioned twice in method 2.
Is method 1, a good practice. If not, in what cases will it fail.
Method 2 is used to prevent minification bugs. In Production when you usually minify your JS/CSS files, the variables' names change to reduce bytes and make the files lighter.
AngularJS relies on DI, which means that it knows which service/provider to inject to your controllers/services according to the name. If it sees $httpProvider, it knows to inject $httpProvider. Once minifaction takes place, the naming will change from:
app.controller('MyController', function (a,b) { //a, b is the change
///
});
Or something of that sort.
Using Method 2, you specify the names as strings, and using those strings AngularJS knows what to inject despite the fact that the minification changed the variables' names.
You can read more about this here.
The recommended way of declaring Controllers is using the array notation:
someModule.controller('MyController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) {
...
$scope.aMethod = function() {
...
}
...
}]);
Dependency Annotation
There are three ways of annotating your code with service name information:
Using the inline array annotation (preferred)
Using the $inject property annotation
Implicitly from the function parameter names (has caveats)
Among These three,Using the inline array annotation is preferred approach.And
the last is simplest way to get hold of the dependencies is to assume
that the function parameter names are the names of the dependencies.
Advantage of implicitly from the function parameter names approach is that there's no array of names to keep in sync with the function parameters. You can also freely reorder dependencies.And disadvantage is If you plan to minify your code, your service names will get renamed and break your app.
Source: this

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.

AngularJS best practices for module declaration?

I have a bunch of Angular modules declared in my app. I originally started declaring them using the "chained" syntax like this:
angular.module('mymodule', [])
.controller('myctrl', ['dep1', function(dep1){ ... }])
.service('myservice', ['dep2', function(dep2){ ... }])
... // more here
But I decided that wasn't very easy to read, so I started declaring them using a module variable like this:
var mod = angular.module('mymodule', []);
mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
mod.service('myservice', ['dep2', function(dep2){ ... }]);
...
The second syntax seems a lot more readable to me, but my only complaint is that this syntax leaves the mod variable out in the global scope. If I ever have some other variable named mod, it would be overridden with this next one (and other issues associated with global variables).
So my question is, is this the best way? Or would it be better to do something like this?:
(function(){
var mod = angular.module('mymod', []);
mod.controller('myctrl', ['dep1', function(dep1){ ... }]);
mod.service('myservice', ['dep2', function(dep2){ ... }]);
...
})();
Or does it even matter enough to care? Just curious to know what the "best practices" are for module declaration.
'Best' way to declare a module
As angular is on the global scope itself and modules are saved to its variable you can access modules via angular.module('mymod'):
// one file
// NOTE: the immediately invoked function expression
// is used to exemplify different files and is not required
(function(){
// declaring the module in one file / anonymous function
// (only pass a second parameter THIS ONE TIME as a redecleration creates bugs
// which are very hard to dedect)
angular.module('mymod', []);
})();
// another file and/or another anonymous function
(function(){
// using the function form of use-strict...
"use strict";
// accessing the module in another.
// this can be done by calling angular.module without the []-brackets
angular.module('mymod')
.controller('myctrl', ['dep1', function(dep1){
//..
}])
// appending another service/controller/filter etc to the same module-call inside the same file
.service('myservice', ['dep2', function(dep2){
//...
}]);
// you can of course use angular.module('mymod') here as well
angular.module('mymod').controller('anothermyctrl', ['dep1', function(dep1){
//..
}])
})();
No other global variables are required.
Of course it depends all on preferences, but I think this is kind of the best practise, as
you don't have to pollute the global scope
you can access your modules everywhere and sort them and their functions into different files at will
you can use the function-form of "use strict";
the loading order of files does not matter as much
Options for sorting your modules and files
This way of declaring and accessing modules makes you very flexible. You can sort modules via function-type (like described in another answer) or via route, e.g.:
/******** sorting by route **********/
angular.module('home')...
angular.module('another-route')...
angular.module('shared')...
How you sort it in the end is a matter of personal taste and the scale and type of the project. I personally like to group all files of a module inside of the same folder (ordered into sub-folders of directives, controllers, services and filters), including all different test-files, as it makes your modules more reusable. Thus in middle-sized projects I end up with a base-module, which includes all basic routes and their controllers, services, directives and more or less complex sub-modules, when I think they could be useful for other projects as well,e.g.:
/******** modularizing feature-sets **********/
/controllers
/directives
/filters
/services
/my-map-sub-module
/my-map-sub-module/controllers
/my-map-sub-module/services
app.js
...
angular.module('app', [
'app.directives',
'app.filters',
'app.controllers',
'app.services',
'myMapSubModule'
]);
angular.module('myMapSubModule',[
'myMapSubModule.controllers',
'myMapSubModule.services',
// only if they are specific to the module
'myMapSubModule.directives',
'myMapSubModule.filters'
]);
For very big projects, I sometimes end up grouping modules by routes, as described above or by some selected main routes or a even a combination of routes and some selected components, but it really depends.
EDIT:
Just because it is related and I ran into that very recently again: Take good care that you create a module only once (by adding a second parameter to the angular.module-function). This will mess up your application and can be very hard to detect.
2015 EDIT on sorting modules:
One and a half year of angular-experience later, I can add that the benefits from using differently named modules within your app are somewhat limited as AMD still does not really work well with Angular and services, directives and filters are globally available inside the angular context anyway (as exemplified here). There is still a semantic and structural benefit though and it might be helpful being able to include/ exclude a module with a single line of code commented in or out.
It also almost never makes much sense to separate sub-modules by type (eg. 'myMapSubModule.controllers') as they usually depend on each other.
I love the angular-styleguide by Johnpapa, and here are some rules that related to this question:
Rule: Named vs Anonymous Functions
Avoid using anonymous functions:
// dashboard.js
angular
.module('app')
.controller('Dashboard', function() { })
Instead, use named functions:
// dashboard.js
angular
.module('app')
.controller('Dashboard', Dashboard);
function Dashboard() { }
As the author says: This produces more readable code, is much easier to debug, and reduces the amount of nested callback code.
Rule : Define 1 component per file.
Avoid multiple components in one file:
angular
.module('app', ['ngRoute'])
.controller('SomeController', SomeController)
.factory('someFactory', someFactory);
function SomeController() { }
function someFactory() { }
Intead, use one file to define the module:
// app.module.js
angular
.module('app', ['ngRoute']);
one file just uses the module to define a component
// someController.js
angular
.module('app')
.controller('SomeController', SomeController);
function SomeController() { }
and another file to define another component
// someFactory.js
angular
.module('app')
.factory('someFactory', someFactory);
function someFactory() { }
Of course, there are many other rules for modules, controllers and services that are quite useful and worth reading.
And thanks to comment of ya_dimon, the above code should be wrapped in IIFE, for example:
(function (window, angular) {
angular.module('app')
.controller('Dashboard', function () { });
})(window, window.angular);
I recently had this conundrum as well. I had started off just like you using the chained syntax, but in the long run it becomes unwieldy with large projects. Normally I'd create a controllers module, a services module and so on in separate files and inject them into my main application module found in another file. For Example:
// My Controllers File
angular.module('my-controllers',[])
.controller('oneCtrl',[...])
.controller('twoCtrl',[...]);
// My Services File
angular.module('my-services',[])
.factory('oneSrc',[...])
.facotry('twoSrc',[...]);
// My Directives File
angular.module('my-directives',[])
.directive('oneDrct',[...])
.directive('twoDrct',[...]);
// My Main Application File
angular.module('my-app',['my-controllers','my-services','my-directives',...]);
But each one of these files was getting way to large as the project grew. So I decided to break them up into separate files based on each controller or service. I found that using angular.module('mod-name'). without the injection array, is what you need for this to work. Declaring a global variable in one file and expecting that to be readily available in another just doesn't work or could have unexpected results.
So in short my application looked something like this:
// Main Controller File
angular.module('my-controllers',[]);
// Controller One File
angular.module('my-controllers').controller('oneCtrl',[...]);
//Controller Two File
angular.module('my-controllers').controller('twoCtrl',[...]);
I did this to the services file as well, no need to change the main application module file you'd still be injecting the same modules into that.
One other practice is to stuff controllers, directives, etc in their own modules and inject those modules into your "main" one:
angular.module('app.controllers', [])
.controller('controller1', ['$scope', function (scope) {
scope.name = "USER!";
}]);
angular.module('app.directives', [])
.directive('myDirective', [function () {
return {
restrict: 'A',
template: '<div>my directive!</div>'
}
}]);
angular.module('app', [
'app.controllers',
'app.directives'
]);
Nothing is left in the global scope.
http://plnkr.co/edit/EtzzPRyxWT1MkhK7KcLo?p=preview
I like to divide my files and my modules.
Something like this:
app.js
var myApp = angular.module('myApp', ['myApp.controllers', 'myApp.directives', 'myApp.services']);
myApp.config(['$routeProvider', function($routeProvider) {
/* routes configs */
$routeProvider.when(/*...*/);
}]);
directives.js
var myDirectives = angular.module('myApp.directives', []);
myDirectives.directive( /* ... */ );
service.js
var myServices = angular.module('myApp.services', []);
myServices.factory( /* ... */ );
Im not a big fan of the "chained style", so I prefer to write down my variable always.
I suggest to follow Angularjs Style Guide.
They handle all concept from naming convention, to modularize your app and so on.
For angular 2, you can check Angular 2 Style Guide
For me, chaining is the most compact way:
angular.module("mod1",["mod1.submod1"])
.value("myValues", {
...
})
.factory("myFactory", function(myValues){
...
})
.controller("MainCtrl", function($scope){
// when using "Ctrl as" syntax
var MC = this;
MC.data = ...;
})
;
That way I can easily move components between modules, never need to declare the same module twice, never need any global variables.
And if the file gets too long, solution is simple - split into two files, each declaring its own module at the top. For more transparency, I try to keep one unique module per file and name it resembling the full path of the file. This way also I never need to write a module without [], which is a common pain point.

What underlying concept(s) am I not understanding in regard to this AngularJS code snippet?

I've been reading through the tutorial, dev guide, and practicing on my own, but I'm having trouble piecing everything together in my mind with regard to dependency injection.
Question: Within the first code snippet in the linked page below, why is the name of the "service" located in front of $inject and why is the parameter of the service used here again? Or better yet what concepts am I lacking in understanding? I'd like to be able to piece it all together in my head step by step, but I'm still trying to understand how exactly even the globally defined "services/functions" can be written this way.
http://docs.angularjs.org/guide/dev_guide.services.understanding_services
So in that code snippet is injecting the $location service into MyController. So MyController depends on $location so it declares the dependency and its owns the dependency declaration.
Here is the code commented:
// declaring a Controller function
var MyController = function($location) { ... };
// $location service is required by MyController
MyController.$inject = ['$location'];
// Then register the Controller in the module.
// The module is the container that performs DI on the objects within it.
myModule.controller('MyController', MyController);
Typically though you'd do the following to declare the Controller and it's dependencies in one shot that's cleaner. The dependencies are strings at the front of the array before the final function which is the controller being registered. Here is the simpler definition:
myModule.controller('MyController', ['$scope', '$location', function($scope, $location) {
$scope.someFunction = function() {
// do something with $location service in here
};
}]);
Keep in mind this:
"...even the globally defined "services/functions"
The whole point of DI is to not define things globally because global definitions create coupling that make it hard to reuse major portions of your system (ie you can't break apart the system without instantiating the whole thing). Dependency Injection separates the dependency (ie MyController depends on/uses $location service) from where it finds that reference. Beginner developers, and some dense senior devs quite frankly, typically just define things globally and that's how everything gets a reference to their dependencies. DI allows code to simply declare its dependencies so its dependencies can be given to the code by an external entity instead of the code assuming where to get it from. Often this is called the Hollywood Principle - Don't call us we'll call you.
It looks like you're lacking a strong understanding of Dependency Injection in AngularJS.
Once you define a service, it then needs to be injected inside to the controller that is going to use it. The two code samples on that page show the two different methods of injecting the service into the controller.
I'd suggest you look at the docs: AngularJS: Dependency Injection

Resources