Meaning of the empty array in angularJS module declaration - javascript

In my previous question, I understand that the code var app = angular.module('myApp', []); connects the module app to the view myApp.
I would like to know why we are having the empty array [] in the module declaration.
What is the empty array used for?

angular.module('app', []) is to create a new module without any module dependency.
angular.module('app') is to retrieve an existing module whose name is app.

That array is meant to add various module to your current app which
is mentioned in your first part of angular.module as string`, You could simply
say for injecting various dependency.
You could create an n number of module inside your app for each component of angular & then you could combine them into one single app and you can angular.bootstrap or apply it on page using ng-app directive.
Example
Suppose you have an app which has different component like services, factory, filters, directives, etc. You could create a module for each of them. Just for making separation of concern.
angular.module('myApp.filters', [])
angular.module('myApp.services', [])
angular.module('myApp.controllers', [])
angular.module('myApp.directives', [])
angular.module('myApp.constants', [])
And while appending an component to it you could simply use that specific module of it. Like you wanted to add service then you just add that service into myApp.services by doing
angular.module('myApp.services').service('example', function(){
})
And then inside you app.js you could do combine all of this modules to an single module like below.
angular.module('myApp', [
'myApp.services',
'myApp.controllers',
'myApp.directives',
'myApp.directives',
'myApp.constants'
])
While initializing an app you could simply use myApp inside, that would make available all other module to it.
What is the empty array used for?
In you code you are creating an module which doesn't inject any dependency, [] which means it is independent of any other angular module.
Dependency injected inside the [] is nothing but importing module

Angulars API says Passing one argument retrieves an existing angular.Module, whereas passing more than one argument creates a new angular.Module
https://docs.angularjs.org/api/ng/function/angular.module

Related

Does Angular DI work at both Module and Controller level?

There are plenty of examples describing how DI operates at controller level in Angular.js but I am new to Angular and I am looking at the code of creating a new module and when I look at following code:
var app = angular.module("myApp", []);
When it says that if this module is using other modules then we can specify them in in []. Is is also not a kind of Dependency injection?
So would it be correct statement to say that DI works at both Module and Controller level in Angular.JS?
Yes, DI works at both Module and Controller level.
But, the difference is
var app = angular.module("myApp", []);
in the above line you inject modules that myApp module depends upon.
Whereas, at controller level, you inject services.
var app = angular.module("myApp", ['navigation']);
app.controller("appController", function(navDataService){
});
So, when AngularJS bootstrap application, it look at module dependencies and load those modules and make the services available, so that, they can be injected into contoller.

AngularJS Module

I am new in AngularJS.I am learning AngularJS. I found below syntax.
var app = angular.module('myApp', ['ngRoute']);
Here is my question is What does it mean by [ ] this square bracket ??
What are functionalities/responsibilities of myApp and ngRoute ?? What are they doing here ??
Which options are available to use like ngRoute ??
I searched a lot in Google. I got several sample code. But could not get any explanation regarding all these things.
Thnanks
As per the angular module developer guide found here: https://docs.angularjs.org/guide/module
<div ng-app="myApp">
<div>
{{ 'World' | greet }}
</div>
</div>
var myAppModule = angular.module('myApp', []);
The reference to myApp module in <div ng-app="myApp">. This is what bootstraps the app using your module.
The empty array in angular.module('myApp', []). This array is the list of modules myApp depends on.
I suggest you read the official documentation as well: https://docs.angularjs.org/api/ng/function/angular.module
Basically [ ] means the module list, your module depends on.
Suppose you write a angular module myApp that depends on ngRoute that is an another angular module.
The benefits of that you can inject lots of third party angular module that works on different different area. So you dont have to reinvent the wheel. By injecting ngRoute you can easily get the functionality of routing in your app.
I think the description I write helps you to understand clearly
In javascript, you can define a array like this:
var arr = [];
the [] here is the same as the [] around 'ngRoute', that means the second parameter of angular.module() method is a array.
you can define a module like this as well:
var app = angular.module('awesomeApp', ['ngRoute', 'ngAnimate', 'ngXXX']);
the first param 'awesomeApp' is the name of your module, the second param [ngRoute', 'ngAnimate', 'ngXXX'] is the dependencies of your module.
Here the dependency will provide some interfaces or features or functions or any stuff that will help you to make your module work as your expectation.
What you pass as the second arguments is the list of your dependencies.
In a basic app, is would be just an empty array.
var app = angular.module('myApp', []);
Basically it could be anything, from the 3rd party plugins that you download to other plugins that you yourself wrote to use. You can find plenty plugins here: http://ngmodules.org/
I'd suggest you to read the angular official documents.
This syntax defines a module.
var app = angular.module('myApp', ['ngRoute']);
myApp this is the name of the app, this is just a string.
[ngRoute] within the square brackets are the modules you'd like to inject (the notion of dependency injection). Some common ones you might have seen or will see include ui.bootstrap, restangular, ui.select etc.
Two things worth mentioning:
Please be careful to not mix it up with the module referencing syntax (without the square brackets):
Module definition
angular.module('myApp', []);
Module referencing
angular.module('myApp');
Usually, it's better practice to simply write the module definition out instead of assigning it to a variable, as in
Module definition
angular.module('myApp', []);
instead of
var app = angular.module('myApp', ['ngRoute']);
You can have a look at Papa John's style guide for more information.
https://github.com/johnpapa/angular-styleguide
Hope this helps. :)

maintainable way of injecting dependencies in angularjs

I am wondering how can I inject dependencies in more readable way in angular. I am more interested in AMD(requirejs) way. Like following:
define(function (require) {
var ModuleOne = require("ModuleOne"),
ModuleTwo = require("ModuleTwo");
var ThisModule = (function () {
// code here
})();
return ThisModule;
});
Is it possible to inject dependencies above way in angularjs or is there any better way to do it then current way in angularjs?
From the Angular JS official website
Angular modules solve the problem of removing global state from the
application and provide a way of configuring the injector. As opposed
to AMD or require.js modules, Angular modules don't try to solve the
problem of script load ordering or lazy script fetching. These goals
are orthogonal and both module systems can live side by side and
fulfil their goals.
Hence, purpose of both the libraries(RequireJS and AngularJS) is totally different. The dependency injection system built into AngularJS deals with the objects needed in a component; while dependency management in RequireJS deals with the modules or, JavaScript files.
In requireJS, Objects of loaded modules are cached and they are served when same modules are requested again. On the other hand, AngularJS maintains an injector with a list of names and corresponding objects. In this case, Object is served whenever it is referenced using the registered name.
Generally we inject dependencies in angularJS like
someModule.controller('MyController', function($scope,greeter){
});
If you want an alternative way to inject dependencies in angularJS, you may do something like.
var MyController = function($scope, greeter) {
// ...
}
MyController.$inject = ['$scope', 'greeter'];
someModule.controller('MyController', MyController);
Hope it helps!

Cannot inject AuthenticationController

I am trying to inject a controller into my app.run function, however i keep getting:
Uncaught Error: [$injector:unpr] http://errors.angularjs.org/1.2.10/$injector/unpr?p0=AuthenticationControllerProvider%20%3C-%20AuthenticationController
Here's my app.js:
var app = angular.module('app', [
'AuthenticationModule'
]);
app.run(['$rootScope', 'AuthenticationService', 'AuthenticationController',
function($rootScope, AuthenticationService, AuthenticationController) {
console.log(AuthenticationController);
}
]);
The AuthenticationService is injecting just fine. Why are AuthenticationController not being injected?
As stated in the AngularJS documentation on modules:
Run blocks - get executed after the injector is created and are used
to kickstart the application. Only instances and constants can be
injected into run blocks. This is to prevent further system
configuration during application run time.
In the documentation for controllers, it states:
In Angular, a Controller is a JavaScript constructor function that is
used to augment the Angular Scope. When a Controller is attached to
the DOM via the ng-controller directive, Angular will instantiate a
new Controller object, using the specified Controller's constructor
function.
A controller is an instance constructor function, not an instance itself, as opposed to a service, which is. Therefor, from what I can gather, controllers cannot be injected into a run block.
If you need to configure a controller at start-up time, then use a provider. As it turns out, in angular, controllers (along with directives, filters, and animations) are all simply syntactic sugar for a provider. Providers can be configured using configuration blocks: configuration block documentation
Configuration blocks - get executed during the provider registrations
and configuration phase. Only providers and constants can be injected
into configuration blocks. This is to prevent accidental instantiation
of services before they have been fully configured.

Lazy loading controllers that are in different modules

I am building a large Angular Application. I am trying to lazy load dependencies.
So my application module in app.js looks like
testApp = angular.module('SellerDashboard', [
'ui.bootstrap',
'ngRoute',
'chieffancypants.loadingBar',
'ngAnimate',
'route-segment',
'view-segment',
'Feature1.Index',
'Feature1.My_Listings',
'Feature1.My_Listings.Directives',
'Feature2.Debug',
'Feature2.Index',
'Feature3.Index',
'Feature3.Landing'
]);
Each of these modules have sub modules which has further dependencies.Each of the modules are in seperatefiles .An example file is as follows
var featureApp = angular.module('Feature1.My_Listings', ['Feature1.Services', 'Common.Services', 'CommonDebug.Services','angular-intro']);
listing_app.controller('my_listing', ['$scope', 'fkPaginator', '$routeParams', 'fkLogger', '$q','fkLoaderManager',function ($scope,fkPaginator, $routeParams, fkLogger, $q,fkLoaderManager) { //do somesthing})]);
So my app.js has no direct dependency on 'Feature1.Services' modules. It has dependency of Feature1.My_Listings module (which defines the controllers) which has further dependency on services modules.
[Feature1.Services defines the services has further dependency on other providers its requires]
Now,I do not want my Feature1.My_Listings to be loaded until I go the page that actually require some controller defined in 'Feature1.Services' .So if I am in "My_Listings" page I do not want to load fFeature2 and Feature 3 modules.
Implement lazy loading . The above link shows how to use resolve while changing routes.But then it also makes it mandatory to have all files under one module which is the app module and all controllers to be defined as app.controller("bla bla") using app as the global variable. But in my case I want to lazy load modules and include them dynamically based on the routes.
How do I go about it ?? It would be nice if somebody could help regarding how this can be achieved using requirejs.
So for a very large app is the above way correct for defining controllers,services ,etc or breaking them in to smaller modules like I did is the proper way ??

Categories