12

Generally, I'd do the following and there would be an ng-app in my HTML:

var myApp = angular.module("myApp", []);

myApp.controller("AttributeCtrl", function ($scope) {
    $scope.master = {
        name: "some name"
    };
});

However, I need to manually bootstrap angular because I'm only using it in a part of my app that is loaded via jQuery's $.load(). If I do the following:

main.js - this is where the page I want to use angular on is being pulled in

$("#form").load(contextPath + url, params, function() {
    angular.bootstrap($("#angularApp"));
});

And then the page being pulled in has it's own javascript:

function AttributeCtrl($scope) {
  $scope.master = { name: "some name"};
}

This works, however, ideally, I'd like my controllers to be scoped at the module level. So I modified the above code like so

main.js

$("#form").load(contextPath + url, params, function() {
    angular.bootstrap($("#angularApp", ["myApp"]));
});

and then...

var app = angular.module("myApp"); // retrieve a module

app.controller("AttributeCtrl", function($scope) {
  $scope.master = { name: "some name"};
});

Retrieving the module this way doesn't seem to work, though. Am I doing something wrong?

3
  • Are you getting a module not found message? Is the module declaration and controller factory being run before the bootstrap function call? Commented May 14, 2013 at 14:13
  • 1
    @gregg Just give you the update. They updated the documentation to make it clear. They said you can only pass in predefined modules. Hope it helps. github.com/angular/angular.js/issues/3692 Commented Sep 5, 2013 at 14:43
  • How can you guarantee the time that it takes to do the load to the time you try and reference the module that the module was bootstrapped at that point? Commented Nov 7, 2013 at 6:17

4 Answers 4

3

You cannot create a controller after you've bootstrapped the app. See the documentation for angular.bootstrap.

You should call angular.bootstrap() after you've loaded or defined your modules. You cannot add controllers, services, directives, etc after an application bootstraps.

Sign up to request clarification or add additional context in comments.

Comments

1

I don't know if this is just in the example code you have here but:

angular.bootstrap($("#angularApp", ["myApp"]));

should be

angular.bootstrap($("#angularApp"), ["myApp"]);

Your code for retrieving the module should work.

Comments

0

Updated

They updated the documentation and now it reads like this

Each item in the array should be the name of a predefined module or a (DI annotated) function that will be invoked by the injector as a run block. See: {@link angular.module modules}


It seems a bug.

The way you implemented to retrieve the module is correct. Just quote it from the doc to make it clear since it may not be well-known.

When passed two or more arguments, a new module is created. If passed only one argument, an existing module (the name passed as the first argument to module) is retrieved.

For the problem you mentioned, long story short...

The bootstrap function calls createInjector with the module list ['ng', ['ngLocale', function(){...}] , 'myApp'] (the last one is the module you passed in)

function bootstrap(element, modules) {
    ...
    var injector = createInjector(modules);

Inside createInjector(), it calls loadModules for each module passed in

function createInjector(modulesToLoad) {
    forEach(loadModules(modulesToLoad), function(fn) { instanceInjector.invoke(fn || noop); });

And loadModules calls angularModule, which is initialized as angularModule = setupModuleLoader(window);, which creates the object window.angular.module

function loadModules(modulesToLoad){
    ....
    var moduleFn = angularModule(module); // triggers the error

The the error occurs, since angularModule takes 2nd parameter as requires. Without it, it will throws an exception on this line (line 1148) throw Error('No module: ' + name);

Reported: https://github.com/angular/angular.js/issues/3692

3 Comments

This isn't a bug. You're wrong. Here's a working plnkr plnkr.co/edit/UowJpWYc1UDryLLlC3Be?p=preview
@vin Let's cut it. I don't want to argue with you since you really don't understand what we are talking about here.
Fair enough, maybe I don't understand the problem
0

Not sure if this counts as a bug or an implementation decision (albeit a seemingly poor one). Adding an empty array solves the undefined require problem that you were having and should solve your problem overall.

var app = angular.module("myApp", []); // create a module

app.controller("AttributeCtrl", function($scope) {
   $scope.master = { name: "some name"};
});`

Also, in your fiddle you call {{name}} which won't render. You should be calling {{master.name}}


Edit

Thank you all for the downvotes .. Here's a working example. Good luck!

http://plnkr.co/edit/UowJpWYc1UDryLLlC3Be?p=preview

2 Comments

NO. "When passed two or more arguments, a new module is created. If passed only one argument, an existing module (the name passed as the first argument to module) is retrieved."
So then the solution is to create a new module and then call that module using bootstrap .. var app = angular.module('myApp', []);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.