how angularjs reference module load dependency - javascript

I have a main module, that loads ngRoute service.
angular.module("app", ["ngRoute", "app.settings"]
and my app.settings module is not loading ngRoute service,
angular.module("app.settings", [])
.config(["$routeProvider", function($routeProvider){
$routeProvider.when("/settings", {
template: "{{message}}",
controller:"SettingsController"
});
}])
But I can use $routeProvider in this module.
Does angular module loading order not care? Can I load any dependency any module?

The thing is that your app module is loading the ngRoute, and also is loading your app.settings modules, so the dependency is already injected into your Angular application, so there is no need to injected again.
Does angular module loading order not care?
The order doesn't matter Angular first resolve the dependencies and then compiles the modules, controllers etc.
angular.module("app", ["ngRoute", "app.settings"]
Is the same as
angular.module("app", ["app.settings", "ngRoute"]
However you can run into troubles in some Unit Test scenarios if you only load the module app.settings your test will fail. But in the most cases you are going to load the app module and all the main modules of your Angular application.
Can I load any dependency any module? Short answer, yes.
Long answer: Your ngRoute dependency should be loaded in the main module because is something which your app module is going to need it to define the basic routing, if the dependency is loaded in several modules is not going to throw any error, in fact you should add all the dependencies needed by each module because in large applications there is no guarantee that the ngRoute/myFactory/etc is already loaded.
Update to improve readability

Related

How does AngularJS knows where to look for a module to load?

I have an app module defining dependencies (taken from phonecat-Tutorial) in the directory app:
app.module.js:
angular.module('phonecatApp', [
'phoneList' // (*)
]);
Then, in a directory app/phone-list are the module:
phone-list/phone-list.module.js:
angular.module('phoneList', []);
and component:
phone-list/phone-list.component.js:
angular.module('phoneList').component('phoneList', {...});
From registering the module phoneList in the first snippet at (*), how does AngularJS knows where to fetch the module from? Is the mapping from phoneList to phone-list-directory naming a builtin feature?
AngularJS has a dictionnary of modules. The key in this dictionnary is the string that you give your module when you register it with the following line :
angular.module('phoneList', []);
That's why the previous line must always have been executed in javascript before you can use your module by adding a component (like following line) :
angular.module('phoneList').component('phoneList', {...});
or by injecting your module into another module
angular.module('phonecatApp', [
'phoneList'
]);
The code for relevant modules has to be included in scripts included in the page. This is either done by manually adding various script tags or by task runners like grunt, gulp, webpack etc adding them for you.
If dependency module code doesn't exist angular will throw error
In simpler terms - where the code comes from is not angular's responsibility. It has to already exist for angular to work

AngularJS - Can we remove/delete module?

I'm trying to clear memory of previous module of my app which Im not going to use after I've routed to a different location.
So for example my "WebApp" is my main angular module of my app which has dependency of "catalogApp", "PaymentApp", etc modules. I want to remove the previous module as and when I route from 1 module to another.
So, Can we remove/delete module?
I am not sure about deleting modules as such. But you can use ocLazyLoad to lazy load modules only when they are required.

how ngRoute works in background when include as dependency in angularjs?

When we write angular.module('app',['ngRoute']); what exactly dependencies here mean?
to be precise ngRoute is nothing but a simple angular module like
angular.module('ngRoute',['ng']) in which has $routeProvider
`angular.module('ngRoute',[]).provider('$roteProvider',[function(){}]).services('$route',function(){}).service('$routeParam',function(){})`
Its better to see the angular project in github https://github.com/angular/angular.js/blob/master/src/ngRoute/route.js
Dependencies means the list of modules that particular module in your case 'app' is dependent on , you when you state them as dependencies they get injected in the module at initialization and become available for usage

Inject modules conditionally in AngularJS app

My Angular app structure is like this:
App.js
angular.module('RateRequestApp', [
'RateRequestApp.services',
'RateRequestApp.controllers',
'ui.bootstrap',
'angular-loading-bar',
'textAngular',
'angularFileUpload'
]);
I am using different HTML files for different pages and I am not using
Angular's $route, but still I want to use same app in all pages with different controllers.
As you can see I am injecting third party modules to my app. The problem is that in some pages I don't want some of this modules, How can I avoid them where I don't need them?
Yes you can do it something like this:
var myApp = angular.module('RateRequestApp', [
'RateRequestApp.services',
'RateRequestApp.controllers',
'ui.bootstrap',
'angular-loading-bar'
]);
var lazyModules = ['textAngular', 'angularFileUpload'];
angular.forEach(lazyModules, function(dependency) {
myApp.requires.push(dependency);
});
In this case you may inject the modules conditionally. (But please note, lazy loading of some module may not work where there is some configuration needed.)

Include dependencies in Karma test file for Angular app?

I am trying to get started with Karma tests, adding them to an existing Angular app.
This is my main app definition file:
angular
.module('myApp', [
'ngRoute',
'moduleAdherence'
]);
This is my controller file:
angular
.module('moduleAdherence', [])
.controller('AdherenceCtrl', ['$scope', function ($scope) {
$scope.awesomeThings = [1,2,3,4];
}]);
This is my first stab at a file:
describe('Controller: AdherenceCtrl', function () {
beforeEach(module('myApp'));
var MainCtrl,
scope;
beforeEach(inject(function ($controller, $rootScope) {
scope = $rootScope.$new();
MainCtrl = $controller('AdherenceCtrl', {
$scope: scope
});
}));
it('should attach a list of awesomeThings to the scope', function () {
expect(scope.awesomeThings.length).toBe(4);
});
});
When I try to run this with grunt test, it fails with the following error:
Uncaught Error: [$injector:nomod] Module 'd3' is not available!
You either misspelled the module name or forgot to load it.
If registering a module ensure that you specify the dependencies
as the second argument.
http://errors.angularjs.org/1.2.0/$injector/nomod?p0=d3
at /Users/me/Dropbox/projects/myapp/app/bower_components/angular/angular.js:1498
I don't understand this, because this controller does not Use D3. I do use D3 elsewhere in the app, in a directive, but I'm not registering it with the module (I use the external D3 file).
Why is Karma noticing D3? Shouldn't it be able to test this controller without D3?
In karma configuration file (karma.conf.js) you need to define all libraries.
etc.
// list of files / patterns to load in the browser
files: [
'app/lib/angular/angular.js',
'app/lib/angular-route/angular-route.js',
'test/lib/angular-mocks.js',
'app/app.js',
'app/controllers/*.js',
'app/services/*.js',
'app/*',
'test/spec/**/*.js'
],
Had a similar problem and my solution (inspired someway by #danba comment) was to load the scripts in the files in the exact same order as they were loaded in the index.html.
In my case globbing patterns like app/scripts/**/*.js were causing trouble to karma which constantly threw errors.
Maybe not the most elegant solution to copy all the scripts definitions but worked in the end so my test could finally get back running. Hope it helps.
EDIT: Editing this because today I probably (and hopefully) got the hang of what was going wrong here. So it seems that Karma does not like globbing patterns when the same module is defined in one file and used in many different files. Let's say that your folder structure is like this:
Suppose that in AuthService.js you have your module definition for all your services in that folder, so that that file starts with:
angular.module('myApp.services', [
'myApp.urls',
'ngCookies'
])
Then in all the other files you're just attaching other services to that same module. In the picture tokenService.js would start with:
angular.module('myApp.services');
If everything stays this way everything will probably work. But if by any chance I define the module the other way round, so the module definition is not anymore in the first file of that folder but on another that Karma reads after AuthService then it will throw an error and refuse to complete the tests.
Solution 1
A solution might be to put the module definition in its own file, starting with an underscore. Finally, let all the siblings files depend on that one(s). So the above folder structure should be:
Solution 2
Another - probably better - solution is to mark the files where the modules are defined with a common suffix/extension for example service.module.js while the files that depend on it could be named normally like authService.js, tokenService.js.
The Karma configuration at that point will become something like:
// list of files / patterns to load in the browser
files: [
'app/lib/angular/angular.js',
'test/lib/angular-mocks.js',
'app/app.js',
'app/**/*.module.js', // <-- first the module definitions...
'app/**/*.js', // <-- ..then all the other files
'test/spec/**/*.js'
],
This way karma will load the modules definitions first and then those file that depend on them.
I also had the same issue, in my case problem occured because there were several files per module which is a bad practice since we can point to not initialized module. Solved this by including just one file per module.
Always load the non minified version of angular into karma.
it will display errors and help you better to find out what to change.
In your case, it's the order of the files being loaded by karma.
Check your index.html that you don't include something by a script tag like.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5angular-resource.js"
All your Javascript file need to be in your karma.config.js
Here's a simple solution that worked for me, based on above Solution #1 by #Nobita, AND #danba's comment.
In karma.conf.js, explicitly load the prerequisite file above the pattern that pulls in the rest:
files: [
...
'app/module.js',
'app/*.js'
]
Karma does not seem to mind that the pattern also matches 'module.js'.

Categories

Resources