Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if AngularJS module is bootstrapped

I have an iframe with ASP.NET application, that contains UpdatePanel. I started using Angular inside the application, but things didn't work because of the .NET postbacks.

To solve this, I used this solution:

with (Sys.WebForms.PageRequestManager.getInstance()) {
            add_endRequest(onEndRequest); // regester to the end Request
        }

function onEndRequest(sender, args) {
    angular.bootstrap($('#mainDiv'), ['defaultApp']);
    var rootscope = angular.element('#mainDiv').scope();
    if (rootscope) {
        rootscope.$apply();
    }
}

And it works great.

The problem is that when I dynamically load a different user control in the ASP.NET page, with another ng-controller, Angular throws an error saying the app is already loaded:

App Already Bootstrapped with this Element

So the question is: How can I check if the app is already bootstrapped? Can I reload this module? Can I remove it from the element and than bootstrap it again?

Thanks.

like image 935
Guy Avatar asked Feb 08 '15 09:02

Guy


2 Answers

It's not good practice to access scope from outside the app, so it's not enabled in well-built production applications. If you need to access/apply scope then there's something strange/unsupported about your use case.

However, the right way to check whether an element has been bootstrapped is the way the Angular library does it which is to load up the element and check for an injector. So you'd want angular.element(document.querySelector('#mainDiv')).injector(); which makes your code:

function onEndRequest(sender, args) {
    var element = angular.element(document.querySelector('#mainDiv'));

    //This will be truthy if initialized and falsey otherwise.
    var isInitialized = element.injector();
    if (!isInitialized) {
        angular.bootstrap(element, ['defaultApp']);
    }

    // Can't get at scope, and you shouldn't be doing so anyway
}

Can you tell us why you need to apply the scope?

like image 139
Adam McCormick Avatar answered Sep 21 '22 13:09

Adam McCormick


You could simply check for the scope of mainDiv, if angular.element(document.querySelector('#mainDiv')).scope() is not undefined then that means angular has been not initialized yet.

You code will be like below.

CODE

function onEndRequest(sender, args) {
    //below flag will be undefined if app has not bootsrap by angular.
    var doesAppInitialized = angular.element(document.querySelector('#mainDiv')).scope();
    if (angular.isUndefined(doesAppInitialized)) //if it is not 
        angular.bootstrap($('#mainDiv'), ['defaultApp']);
    var rootscope = angular.element('#mainDiv').scope();
    if (rootscope) {
        rootscope.$apply(); //I don't know why you are applying a scope.this may cause an issue
    }
}

Update

After angular 1.3+ release in later Aug 2015, there it added performance related improvement by disabling debugging information by disabling debug info. So normally we should enable debuginfo option to false to have good performance improvement on Production environment. I don't wanted to write too much about it as its already covered by @AdamMcCormick answer, which is really cool.

like image 34
Pankaj Parkar Avatar answered Sep 18 '22 13:09

Pankaj Parkar