Angular is missing resumeBootstrap function

I am currently trying to set up a new AngularJS project using RequireJS. I started with angularjs-requirejs-seed project . I've used one project in the past using angular / require, but I haven't been able to get it to work with the "NG_DEFER_BOOTSTRAP" method yet.

Here is my main.js file,

'use strict';

require.config({
    paths: {
        jquery: "bower_components/jquery/dist/jquery",
        angular: "bower_components/angular/angular",
        angularRoute: "bower_components/angular-route/angular-route.min",
        angularMocks: "bower_components/angular-mocks/angular-mocks.min",
        text: "bower_components/requirejs-text/text",
        compApp: "components/app",
    },
    shim: {
        'angular' : {'exports' : 'angular'},
        'angularRoute': ['angular'],
        'angularMocks': {
            deps:['angular'],
            'exports':'angular.mock'
        }
    },
    priority: [
        "angular"
    ]
});

//http://code.angularjs.org/1.2.1/docs/guide/bootstrap#overview_deferred-bootstrap
window.name = "NG_DEFER_BOOTSTRAP!";

require([
    'angular',
    'compApp/app'
], function(angular, app) {
    var $html = angular.element(document.getElementsByTagName('html')[0]);

    angular.element().ready(function() {
        angular.resumeBootstrap([app['name']]);
    });
});

      

When I run this I get an error undefined is not a function

on the resumeBoostrap line. When I debug my app and set a breakpoint on resumeBootstrap, I find angular is missing resumeBootstrap method. However window.name is showing NG_DEFER_BOOTSTRAP correctly. Also, if I remove the resumeBoostrap method and just do it angular.bootstrap

, then an app runs that tells me everything else is fine.

Here is my html file,

<!DOCTYPE html>
<!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->

        <link rel="stylesheet" href="css/normalize.css">
        <link rel="stylesheet" href="css/main.css">
        <script src="js/modernizr.min.js"></script>
    </head>

    <body>
        <!--[if lt IE 7]>
            <p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->

        <h1>AngularJS + RequireJS</h1>
        <ul class="menu">
            <li><a href="#/view1">view1</a></li>
            <li><a href="#/view2">view2</a></li>
        </ul>

        <div ng-view></div>

        <script data-main="main" src="bower_components/requirejs/require.js"></script>  
    </body>
</html>

      

+3


source to share


3 answers


I've spent quite a lot of time on this. The problem is caused by the lazy definition of the resumeBootstrap method. angular.js detects the dom is ready via JQLite. When the document is loaded, it runs a method that defines the resumeBootstrap method. The problem is that you cannot force the order of processing between domready and JQLite, if your dependency is already running before the method is defined, you have problems.

The workaround is to force javascript to execute all event handlers before calling resumeBootstrap. I used the setTimeout method for this, for example: setTimeout (angular.resumeBootstrap, 0).



http://javascript.info/tutorial/events-and-timing-depth#the-settimeout-func-0-trick

Hope it helped!

+3


source


According to the angular bootstrap documentation :

If window.name contains the prefix NG_DEFER_BOOTSTRAP! when angular.bootstrap is called, the bootstrap process will be suspended until angular.resumeBootstrap () is called.

angular.resumeBootstrap () accepts an optional array of modules that should be added to the original list of modules that the application should have loaded with.



Here is my snippet to defer angular initialization in requirejs app:

window.name = "NG_DEFER_BOOTSTRAP!";

define(['angular', 'domReady', 'app'], function(ng, domReady){
    domReady(function(document){
        ng.bootstrap(document, ['app']);
        ng.resumeBootstrap();
    })
});

      

+6


source


This is an old question, but I ran into the need for a (semi-) legacy application. Instead of using an event DOM Ready

or some shenanigans, settimeout()

I checked the source code and found this undocumented feature: https://github.com/angular/angular.js/blob/master/src/Angular.js#L1853

if (isFunction(angular.resumeDeferredBootstrap)) {
    angular.resumeDeferredBootstrap();
}

      

This was added to this commit: https://github.com/angular/angular.js/commit/c69caa7beee4e920f8f587eb3e943be99864a14f . Since this is undocumented, you should use it at your own risk, but I doubt anything will change since angularjs has been in LTS for a while now.

This code will run if the bootstrap process has been delayed, and therefore would be an ideal hook function to place your call angular.resumeBootstrap()

.

And an example:

angular.resumeDeferredBootstrap = function () {
    // perform actions that need to happen before bootstrapping here
    angular.resumeBootstrap();
    // you could also do some async work in here and make sure bootstrapping happens after
    someAsyncFunctionThatReturnsAPromise().then(function () {
        angular.resumeBootstrap();
    });
};

      

0


source







All Articles