Is it possible to hand-load/unload modules using angular.bootstrap?

My dilemma lies in creating a dynamic single page application that can load and unload AngularJS apps on demand within a designated "main content" section when selecting different menu options.

Despite my efforts, I am consistently encountering the ng:btstrpd error whenever attempting to utilize the angular.bootstrap function.

The apps are loaded using the following code snippet:

var mainContent = document.getElementById('main-content');
window.loadApp = function(modules) {
    angular.bootstrap(mainContent, modules);
}

For reference, here is a jsfiddle link: http://jsfiddle.net/010b62ry/

I have experimented with removing and reinserting the DOM element, but encountered unexpected results such as duplicates. It appears that the modules are not being properly unloaded, as indicated by the presence of numerous <!-- ngView: --> comments.

Do you have any insights on how to implement this functionality successfully? Bonus points if the memory is effectively released when transitioning between applications.

Additionally, it is crucial for the modules to operate independently and manage their own routes, especially since some may be developed by external parties with no access to the source code of the main application. The goal is to initiate these modules as self-sufficient Angular applications.

Answer №1

After stumbling upon a discussion on How to destroy an angularjs app?, I decided to experiment with code to recreate the main-content div.

Here is the HTML code snippet:

<nav>
    <a onclick="loadApp(['app1'])">Load app n°1</a>
    <a onclick="loadApp(['app2'])">Load app n°2</a> 
</nav>
<div id="main-content-wrap">
    <div id="main-content" class="app">
        <div ng-view></div>
    </div>
</div>

Here is the JavaScript code snippet:

angular.module('app1', ['ngRoute']);
angular.module('app1')
.config(['$routeProvider', function ($routeProvider) {
    $routeProvider
    .otherwise({
        template: 'hello app n°1'
    });
}]);
angular.module('app2', ['ngRoute']);
angular.module('app2')
.config(['$routeProvider', function ($routeProvider) {
    $routeProvider
    .otherwise({
        template: 'hello app n°2'
    });
}]);

var mainContent = document.getElementById('main-content');
var mainContentWrap = document.getElementById('main-content-wrap');
var mainContentHTML = mainContentWrap.innerHTML;
window.loadApp = function(modules) {
    if (window.currentApp) {
        destroyApp(window.currentApp);
        mainContentWrap.removeChild(mainContent);
        mainContentWrap.innerHTML = mainContentHTML;
        mainContent = document.getElementById('main-content');
    }
    window.currentApp = angular.bootstrap(mainContent, modules);
}

function destroyApp(app) {
    /*
* Iterate through the child scopes and kill 'em
* all, because Angular 1.2 won't let us $destroy()
* the $rootScope
*/
    var $rootScope = app.get('$rootScope');
    var scope = $rootScope.$$childHead;
    while (scope) {
        var nextScope = scope.$$nextSibling;
        scope.$destroy();
        scope = nextScope;
    }

    /*
* Iterate the properties of the $rootScope and delete 
* any that possibly were set by us but leave the 
* Angular-internal properties and functions intact so we 
* can re-use the application.
*/
    for(var prop in $rootScope){
        if (($rootScope[prop]) 
            && (prop.indexOf('$$') != 0) 
            && (typeof($rootScope[prop]) === 'object')
           ) {
            $rootScope[prop] = null;
        }
    }
}

To see it in action, check out the Fiddle http://jsfiddle.net/010b62ry/5/

Although the solution works, it feels like performing black magic. My suggestion would be to have one app with multiple controllers for a cleaner approach.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to append data to the end of an object using ReactJS Hooks?

Looking to set up a checkbox page in ReactJS where data is filtered by checkboxes from different categories using ReactJS hooks. Currently, I am storing the selected checkboxes as an object: { color: 'orange', shape: 'square' } ...

Determine whether a subdomain is present within an ajax file in php

Looking for assistance with checking the existence of a 'Subdomain' in a file called '\example\sites'. Here's the code: $form = array() ; $form['name'] = "install"; $form['action'] = "?step=2"; $for ...

Explore how to set up Express with React without resorting to using create-react

I am familiar with the react and Node.js Express bundle, but I require assistance. While this question may have been posed by someone else before, I have not come across a similar query within the same framework. The specific question is: How can queries ...

A guide to showcasing tabs as a navigation menu based on media size using AngularJS

Help needed with creating a navigation menu that includes nav-icons on specific media screen sizes. The goal is to display all tabs as a list when clicking on the nav-icon. An attempt was made to implement a navbar, but it interfered with the tab styling. ...

Node.js Application with Role-Based Login

I am currently working on implementing role-based administration. When a user is created, the database stores a "1" for Admin or a "2" for a normal user. I want to retrieve this information from the database and display the corresponding start page based o ...

Getting an error message of 'Unable to locate Firebase Storage Default Bucket on the server?

I'm currently facing an issue with the server not being able to locate the bucket. To troubleshoot, I've stored the token and other crucial details in a separate file as a string. Afterwards, I split it and utilize the relevant text in my Javascr ...

What is the best way to retrieve data from app.post within react.js?

//server.js app.post('/trip', function(req,res){ var params = "something"; getResult(params).then((db)=>{ // I am trying to access the variable called "db" in my App.js(React) file, but I am unsure of how to do so. res.s ...

Using ExpressJS and Jade to submit a form using the POST method and redirecting to a specified path

I am exploring node, express and jade for the first time and working on a small application that requires users to enter their name and password in a form. The app then redirects them to a path based on their username. Here is the code snippet to achieve ...

angular establish Header when an image is loaded

Every request to authenticate with the server requires a special value in the HTTP header. The code I am currently using is as follows: <img ng-if="content.image" src="{{img(content.image)}}"> and var app = angular.module('myApp', []); ...

Manipulating the value of an array obtained from an API alters its data when trying to log it in the render function of a React TSX component

My program can fetch data from an API I created using a component that interacts with the backend: import React, { Fragment, useEffect, useState } from 'react' import { Button, Stack } from '@mui/material'; import TabsComponent from &ap ...

Activate the bootstrap modal display using PHP code

Can someone help me trigger the modal('show') event using PHP code? I attempted the following: if(isset($_POST['Edit'])){ echo "<script> $('#Modal').modal('show') </script>"; } I tested this code, but i ...

Tips for creating a partial matching filter on an array using elements from a separate array

My goal is to filter an array by finding partial matches from another array. To illustrate, consider the following arrays: Array1 = categories: 292300, categories: 300, categories: 292500280 Array2 = 300, 498 After filtering, ...

Encountering the error message: "TypeError [ERR_INVALID_ARG_TYPE]: The initial parameter should either be a string, Buffer instance, or Uint8Array."

Having trouble with the payment gateway API and subscription creation. Encountering an error that I can't seem to resolve even after debugging. Despite my best efforts, the error persists. The form and everything else seem to be in order, but the err ...

PHP code cannot be outputted to JavaScript due to a syntax error

Although there is a syntax error, the code seems to be working. I am curious about how to make it syntactically correct. The provided code snippet is part of a script that sets up variables for an Ajax call. Depending on the scope, the corresponding varia ...

Ensure you always achieve Infinity by accurately calculating the bounding box of objects in A-Frame

When using three.js in my A-Frame scene, I am trying to obtain the bounding box of objects. let boundingBox = new THREE.Box3().setFromObject(element.object3D); However, the 6 values in the boundingBox always default to Infinity or -Infinity as stated in ...

Accessing Ionic rootScope within the config stateprovider - A step-by-step guide

Is it possible to access the value of $rootScope in the following line? .config(function($stateProvider, $urlRouterProvider) { $stateProvider // I am trying to retrieve the value of $rootScope here. } ...

Web page experiencing "increased magnification during loading"

I've been experiencing an issue with my mobile site where the page loads as if it's zoomed in every time. I can easily scale it on a touch phone to make it look right, but I'm looking for ideas on how to prevent this from happening altogethe ...

Navigating to a different page in the app following a document update: a step-by-step guide

I am facing an issue with a page where I am trying to print a specific DIV using the script below... function printReceiptDiv() { var divElements; if (vm.isDLR) { divElements = document.getElementById("DLRreportCont ...

Using Puppeteer-cluster along with cheerio in an express router API results in an unexpectedly blank response

I am currently working on developing an API using express, puppeteer-cluster, and cheerio to extract anchor elements containing specific words that can be used as query parameters. My aim is to utilize puppeteer to capture dynamically generated elements as ...

Navigating through tabs in a Meteor application: How to maintain the active tab when using the back button

I am working on a multi-page meteor application where each page includes a navigation template. To switch between pages, I am using iron-router. The user's current page is indicated by setting the appropriate navigation link's class to 'ac ...