Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load an angular application inside another angular application

Tags:

I have two angular application say A and B. Now in B application's One tab i want to load entire application A. How do i achieve this?

Please let me know how to achieve this functionality. Does angular has any special tag which i can use

like image 216
user2900572 Avatar asked Mar 13 '20 09:03

user2900572


1 Answers

One solution to your problem might be to create the tag you are asking for yourself. I implemented Angular application A in Angular application B by a technique named web component or Angular elements as stated above, see e.g. https://www.techiediaries.com/angular/angular-9-elements-web-components/

In the following steps a tag shiny-app-a is defined in application A which is used later on in application B by importing the JavaScript files of A into B and referencing them by the tag.

It works in the following environment:

  • Angular CLI: 11.0.2
  • Node: 12.16.1
  • OS: win32 x64

The steps to make it run are:

1. Create application A

This application additionally needs the package @angular/elements.

1.1. Create the skeleton of application A

$ ng new App-A
$ cd  App-A
$ ng add @angular/elements

1.2. Apply changes to app.modules.ts to create the web component / element and define the corresponding tag shiny-app-a

My app.modules.ts looks like this:

import { BrowserModule } from '@angular/platform-browser';
// import Injector
import { Injector, NgModule } from '@angular/core';
// import createCustomElement
import { createCustomElement } from '@angular/elements';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
  AppComponent
  ],
  imports: [
  BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {

  constructor(private injector: Injector){}

  ngDoBootstrap(){
    const el = createCustomElement(AppComponent, {injector:this.injector});
    // Here you define your new tag shiny-app-a
    customElements.define('shiny-app-a', el);
  }
 }

1.3. Build project

$ ng build --prod --output-hashing none

This generates among others the files:

  • runtime.js
  • main.js
  • polyfills.js

You will find them in the folder [...]\App-A\dist\App-A

1.4. Test it

Run

$ ng serve

and see in the browser your newly built application A.

2. Create application B

Note: no @angular/elements is needed here.

2.1. Create the skeleton of application B

$ ng new App-B

2.2. Copy the files from application A to a folder accessible by application B

In this example I use the folder [...]/src/assets.

$ cd App-B/src/assets/

and copy the JavaScript from application A to this folder, i.e.:

  • [...]/App-A/dist/App-A/main.js
  • [...]/App-A/dist/App-A/polyfills.js
  • [...]/App-A/dist/App-A/runtime.js

2.3. Adapt source of application B to use the tag defined in step 1.

2.3.1 Make custom elements known to application B in app.module.ts

The crucial item to implement is CUSTOM_ELEMENTS_SCHEMA. My app.modules.ts of application B looks like this:

import { BrowserModule } from '@angular/platform-browser';
// import CUSTOM_ELEMENTS_SCHEMA
import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule
  ],
  // add schemas
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
2.3.2 Load JavaScript from external source in app.component.ts

The JavaScript files may also be loaded from any source. In this case the files are loaded by OnInit() from the [...]/assets folder. Thus my app.component.ts of application B looks like this:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  title = 'App-B';

  ngOnInit() {
    this.loadScript('/assets/runtime.js');
    this.loadScript('/assets/main.js');
    this.loadScript('/assets/polyfills.js');
  }

  public loadScript(url: string) {
    const body = <HTMLDivElement> document.body;
    const script = document.createElement('script');
    script.innerHTML = '';
    script.src = url;
    script.async = false;
    script.defer = true;
    body.appendChild(script);
  }
}
2.3.3 Use tag in app.component.html

Replace anything from the file app.component.html and just by:

<shiny-app-a></shiny-app-a>

2.4. Test it

Run

$ ng serve

and see in the browser application A in application B.

like image 58
Rudolf Starosta - Rudi Avatar answered Sep 30 '22 17:09

Rudolf Starosta - Rudi