Load controller after bootstrap angularjs - javascript

I am using requirejs and angularjs to load the module inside my application.
The problem I am facing is I dont know how to load the controller after angular has been bootstrapped. Here is my code :
main.js :
require(['app', //all my scripts go here
function(){
angular.bootstrap(document, ['myApp']);
});
app.js :
define([], function(){
var myApp = angular.module('myApp', ['ngRoute']);
$routeProvider.
when('/home', {
templateUrl : 'partials/home.html',
controller : 'UserRegisterCtrl'
}).
otherwise({
redirectTo : '/home'
})
return myApp;
})
controller.js
define(['app'], function(app){
app.controller('MyCtrl', function($scope){});
})
myApp.html
body(ng-app)
<div ng-controller = 'MyCtrl'></div> <-- I can not put MyCtrl here
because I think the MyCtrl has been declared before myApp has been bootstrapped
Therefore I really need to know if there is a way to load the MyCtrl controller after myApp has been bootstrapped. I am really new to Angularjs. Any help would be really appreciate.

If you are manually bootstrapping your angular app there is no need for ng-app, because this is just a directive that pretty much does the same thing.
This little trap caused some people a headache before:
Why do I need to angular.bootstrap even when I declare ng-app="MyApp" in JSFiddle
angular bootstrapping issues angular.bootstrap not working on my apps

When you use ng-app in your html, the bootstrap happens automatically. In this case, it depends what you put in the <script> tag in your index.html.
I am assuming that you follow the RequireJS usage where you load angular using RequireJS. If so, make sure you declare the dependency of angular to your app using shim. If that is not the case, please state how your are loading angular and share the content of your main.js.
It was really tricky for me to get RequireJS to work with AngularJS so I created following project that helped me deal with the complexity:
http://marcoslin.github.io/angularAMD

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 dependency injection sharing its dependencies with parent module

I have an AngularJS module:
angular.module("app", ['ui.bootstrap', 'ngRoute', 'ngGridPanel']).config(function($routeProvider) {
As you can see it has ngGridPanel included via dependency injection.
Here is the definition of ngGridPanel's module/directive:
angular.module('ngGridPanel', ['ngAnimate']).directive('gridPanel', ['$animate', '$compile', '$window', '$document', '$timeout', function ($animate, $compile, $window, $document, $timeout) {
As you can see, it refers to ngAnimate.
The problem I am having is that once I inject ngGridPanel into my app, every element in my app is suddenly attempting to be animated.
Now, as described in this Angular.js GitHub issue, ngAnimate will assume everything should be animated. Once I realized this is the expected behaviour, I realized that I never included ngAnimate into my app module in the first place.
So why would it be affecting my entire application? Shouldn't it only take effect in the directive that belongs to the ngGridPanel module?
So how is ngAnimate affecting the parent module scope? Is this normal?
Side-note: At this point I haven't even utilized the ngGridPanel directive at all. I have merely injected it into my app.
Side-note 2: Once I implemented a class name filter ($animateProvider.classNameFilter(/enable-animate/);) in my app, animations stopped on all my elements but remained working in the ngGridPanel directive without having to add the enable-animate class anywhere.
If you depend on ngGridPanel and ngGridPanel depends on ngAnimate, then you depend on ngAnimate as well.
It is the exact same to you as if you had defined your app with
angular.module("app", ['ui.bootstrap', 'ngRoute', 'ngGridPanel', 'ngAnimate'])
.
As for your Side-note 2, it seems likely that they have configured it to use something like .classNameFilter() as well so that animations wouldn't break if the user of their library decided to configure it differently, such as you did. I don't know too much about ngAnimate so that's just a hunch.

Why can't AngularJS resolve this dependency

MyApp.js:
'use strict';
angular.module('MyApp', [
'ngRoute',
'MyApp.components.hello',
'MyApp.pages.index',
'MyApp.pages.upload'
]).
config(['$routeProvider', 'HelloService', function($routeProvider, HelloService) {
$routeProvider.
when('/',
{
templateUrl: 'pages/index/index.html',
controller: 'IndexController'
}).
when('/upload',
{
templateUrl: 'pages/upload/upload.html',
controller: 'UploadController'
}).
otherwise({redirectTo: '/'});
HelloService.init({
facebook : ID_HERE
});
}]);
hello-service.js:
'use strict';
angular.module("MyApp.components.hello", []).
factory("HelloService", function()
{
return window.hello; //assume hello has been loaded
});
When I try to run it, I get the error Error: [$injector:unpr] Unknown provider: HelloService. Why? HelloService is clearly defined in MyApp.components.hello, which is included as a dependency of the main application. So why can't it find HelloService?
Check this article:
Understanding Dependency Injection by josepot
and this section
Configuring Providers
You may be wondering why anyone would bother to set up a full-fledged provider with the provide method if factory, value, etc. are so much easier. The answer is that providers allow a lot of configuration. We've already mentioned that when you create a service via the provider (or any of the shortcuts Angular gives you), you create a new provider that defines how that service is constructed. What I didn't mention is that these providers can be injected into config sections of your application so you can interact with them!
First, Angular runs your application in two-phases--the config and run phases. The config phase, as we've seen, is where you can set up any providers as necessary. This is also where directives, controllers, filters, and the like get set up. The run phase, as you might guess, is where Angular actually compiles your DOM and starts up your app.
So, where is the issue?
We can ask JUST for Providers to be injected into .config()
BUT - they are used in .config() just to be configured, not to be used
I don't think you can inject a service to config block.
Module Loading & Dependencies
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.
Config is too early stage to star working with services, providers and factories.
Try moving that HelloService initialization part to run, like that:
.run(['HelloService', function(HelloService) {
HelloService.init({
facebook : ID_HERE
});
}])

How to declare specific module with Angular

I would to declare specific module because
I load on every page all my angular files..
It's huge.
I want to load specifically angular files on each page.
My app.js file that looks like this :
var testApp = angular.module(
'testApp', [
'MainCtrl',
'AdminCtrl',
'UserCtrl',
'ArticleCtrl',
'ArticleService',
'MediaService',
'UserService',
],
function($interpolateProvider) {
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
}
);
But it wants to declare modules that are no longer loaded.
So instead of making a specific app.js for each page I need..
Anyone has a better idea ?
Thank you.
You can make use of requirejs where modules will be loaded on demand.
A very nice tutorial how to achieve this:
Lazy loading angular components

Best practices to manage dependencies in Angular JS

I really enjoy the use of AMD to manage dependencies.
Now I'm getting started with Angular, in that case things become more complicated, because in one file we refer to a certain object that we admit to have already been created and this requires to make the script tags all organized and so on.
Another thing I noticed is that as the app grows there will be many script tags and more things to grant to be in order. I found ways to make AMD work with Angular.js, but I really didn't like it because it didn't seem natural.
What are the best practices to manage dependencies in Angular JS, making it easier to maintain the app as it grows?
I'd suggest Require.js which does implement AMD. There's a great example of how to configure your main.js (the entry point for a require.js application) and test-main.js (entry point for karma tests) here: https://github.com/tnajdek/angular-requirejs-seed.
Notes:
make sure to use paths and shim for dependent modules that you want to expose to your application but that are not available as require.js modules.
make sure you keep in mind the distinction between angular.js's concept of modules and require.js modules. Require.js modules are about describing file dependencies and loading in the correct fashion. Angular modules are about enabling dependency injection, once this loading is done correctly. You'll end up with code that looks like this example:
example app.js
define([
'angular', //as defined in the requirejs shim config
'filters', //as defined in the filters.js
'services', //as defined in services.js
'directives', //in directives.js
'controllers', //in controllers.js
'angularRoute',//as defined in the requirejs config
],function(angular,filters,services,directives,controllers,angularRoute){
'use strict';
//angular.js module definition syntax: Declare app level module which depends on filters,services,controllers,directives, and angular globals
var angularappModule = angular.module('angularapp', [
'ngRoute',
'angularapp.filters',
'angularapp.services',
'angularapp.directives',
'angularapp.controllers'
]);
angularappModule.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/angularapp', {templateUrl: 'partials/angularapp.html', controller: 'angularappCtrl'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/angularapp'});
}]);
return angularappModule;
});

Categories