3

I can't seem to add a controller after I bootstrap AngularJS. The exception I get indicates that the passed controller function is not a function. However, in the Chrome debugger it shows as the expected function.

(I realize that I am not using the declarative style of initializing AngularJS, I am exploring the framework.)

Exception

Error: Argument 'MediaLoaderController' is not a function, got undefined
    at Error (<anonymous>)
    at $a (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:16:453)
    at qa (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:17:56)
    at $get (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:52:219)
    at http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:43:348
    at m (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:6:494)
    at i (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:43:213)
    at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:39:307)
    at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:39:324)
    at e (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js:39:324) angular.min.js:62
(anonymous function) angular.min.js:62
$get angular.min.js:52
$get.e.$apply angular.min.js:88
(anonymous function) angular.min.js:16
d angular.min.js:27
c angular.min.js:16
rb angular.min.js:16
Bootstrapper.instance.bootstrapAngularJS bootstrapper.js:19
(anonymous function) slide_template_angularjs.jsp:20
x.Callbacks.c jquery.js:3048
x.Callbacks.p.fireWith jquery.js:3160
x.extend.ready jquery.js:433
q

HTML

<html>
    <head>
        <title></title>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>        
        <script src="/js/bootstrapper.js"></script>
        <script language="JavaScript">

            var bootstrapper = null;
            var controllerLibrary = null;

            $(document).ready( function(){
                bootstrapper = new Bootstrapper();
                controllerLibrary = new ControllerLibrary(); 

                bootstrapper.bootstrapAngularJS();
                bootstrapper.myModule.controller( "MediaLoaderController", controllerLibrary.MediaLoaderController );               
            });
            </script>
    </head>
    <body>
        <div ng-controller="MediaLoaderController">
            {{status}}
        </div>
    </body>
</html>

JavaScript

function Bootstrapper() {

    var instance = new Object();

    instance.myModule = null;
    /*
     * Bootstrap AngularJS and initialize myModule
     */
    instance.bootstrapAngularJS = function() {
        instance.myModule = angular.module('myModule', []);
        angular.bootstrap(document, ['myModule']);
    };

    return instance;
}


function ControllerLibrary() {
}

ControllerLibrary.prototype.MediaLoaderController = function($scope) {
    $scope.status = "loading";
};
2
  • It works if you define MediaLoaderController globally (function MediaLoaderController () { ... }), but I'm not sure that's what you want. Commented Oct 2, 2013 at 20:48
  • @Langdon: Thanks. Yeah not really. Trying to experiment with how to organize and execute stuff. All I can think is that AngularJS is 'cheating' somehow and not really taking the function reference from the call to controller(). Commented Oct 2, 2013 at 20:54

1 Answer 1

3

You have to register the controller before bootstrap happens, otherwise AngularJS can't find the controller and throw the error. See the working plunker here. Extract below.

function Bootstrapper() {
    var instance = new Object();
    instance.myModule = angular.module('myModule', []);
    instance.bootstrapAngularJS = function() {
        angular.bootstrap(document, ['myModule']);
    };
    return instance;
}

$(document).ready( function(){
    bootstrapper = new Bootstrapper();
    controllerLibrary = new ControllerLibrary(); 
    bootstrapper.myModule.controller( "MediaLoaderController", controllerLibrary.MediaLoaderController );               
    bootstrapper.bootstrapAngularJS();
});
Sign up to request clarification or add additional context in comments.

2 Comments

Suppose we did want to add the controller after starting angular (for example the ng-controller node did not exist at first, but was added later by some AJAX outside of Angular), could we then restart Angular to find new controllers?
You can register a controller any time, but if AngularJS can't find it when AngularJS needs it, then there will be an error. As long as the code to lookup the controller happens after the controller is registered, you'll be fine.

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.