Encountering an issue in Angular 4 AOT Compilation when trying to load a Dynamic Component: Error message states that the

My Angular application is facing challenges when loading dynamic components. Everything works smoothly with the JIT ng serve or ng build compilation. Even with AOT

ng serve --prod or ng build --prod
, I can still successfully build the application. Lazy loading modules are also functioning as expected. However, when an event is triggered to load a dynamic component from the landing page, I encounter the following error:

vendor.fbd3ddffb0a9e35bbf55.bundle.js:1 ERROR Error: Uncaught (in promise): 
Error: Runtime compiler is not loaded
Error: Runtime compiler is not loaded
at Z (vendor.fbd3ddffb0a9e35bbf55.bundle.js:1)
...

<p>To resolve the above error, I applied an injector in the dynamic component like this:</p>

<pre><code>export class DynamicComponent {
private injector: Injector;
private compiler: Compiler;
constructor(injector: Injector) {
    this.injector = ReflectiveInjector.resolveAndCreate(COMPILER_PROVIDERS,
        injector);
    this.compiler = this.injector.get(Compiler);
}
}

After fixing the previous error, I encountered the following issue:

vendor.fbd3ddffb0a9e35bbf55.bundle.js:1 ERROR Error: Uncaught (in promise): 
Error: No NgModule metadata found for 'l'
Error: No NgModule metadata found for 'l'
at t.FDXN.t.resolve (dynamic.module.c493eec4648091b2c9b3.chunk.js:1)
...

<p>Despite extensive research on the internet and platforms like Stack Overflow, I have been unable to find a solution that works for me.</p>

<p>The structure of my dynamic component is as follows:</p>

<pre><code>import { Component, Input, Output, ViewContainerRef, Compiler, ..., }
...
@Component({
selector: 'app-dynamic-viewer',
...
})

<p>Application environment:</p>

<pre><code>@angular/cli: 1.3.0-beta.1
node: 6.9.4
os: win32 x64
@angular version: 4.3.6

If you have any workaround solutions or insights, please feel free to share. Any input would be greatly appreciated.

Answer №1

I encountered a similar issue before, and here is how I resolved it. Let's assume that you need to dynamically load the UserComponent with AOT compilation from your landing page.

User Module Configuration

@NgModule({
  ...
  entryComponents: [UserComponent]
})
export class UserModule {
  static entry = UserComponent
}

An example of your basic landing page:

Dynamic Component Template

<div>
    <ng-template #pageContainer></ng-template>
</div>    
<div *ngFor="let page of pageData">
    <div (click)="selectPage(page)">
        <div>{{page.title}}</div>
    </div>
</div>

When selecting a page on your landing page to load the component dynamically, provide the absolute path of the respective module. For the user page, the value of currentPage.modulePath could be something like

app/modules/pages/user/user.module#UserModule
. Finally, you can load your entry component as follows:

openWebApp(path: string) {
        this.systemJsNgModuleLoader.load(path)
            .then((moduleFactory: NgModuleFactory<any>) => {
                const entryComponent = (<any>moduleFactory.moduleType).entry;
                const moduleRef = moduleFactory.create(this.injector);    
                const compFactory = moduleRef.componentFactoryResolver.resolveComponentFactory(entryComponent);
                this.componentRef = this.pageHost.createComponent(compFactory);
            });
    }

The dynamic component implementation:

Dynamic Component Typescript

import { Component, Input, Output,   NgModuleFactory, ViewContainerRef, Compiler, ComponentFactory, ComponentFactoryResolver, ModuleWithComponentFactories, ComponentRef, ReflectiveInjector, SystemJsNgModuleLoader, OnInit, OnDestroy, ViewChild, Injector } from '@angular/core';
import { Http } from '@angular/http';
import { Observable, Subscription } from 'rxjs/Rx';    
import { COMPILER_PROVIDERS } from '@angular/compiler';
import * as _ from 'lodash';    
import { Page } from './interfaces/page';
import { PageService } from './services/page.service';
import { ActivePageService } from './services/active-page.service';

@Component({
    selector: 'app-dynamic-viewer',
    host: { 'class': 'template-wrapper dynamicviewer' },
    templateUrl: './dynamic.component.html',
    styleUrls: ['./dynamic.component.less'],
    providers: [PageService, ActivePageService]
})
export class DynamicComponent implements OnInit, OnDestroy {
    // Class properties and methods omitted for brevity
}

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 pause function execution until a user action is completed within a separate Modal?

I'm currently working on a drink tracking application. Users have the ability to add drinks, but there is also a drink limit feature in place to alert them when they reach their set limit. A modal will pop up with options to cancel or continue adding ...

Content that is displayed by default for ng-content when utilizing ngIf

I have created an Angular 9 component called inner: <div #ref> <ng-content select="[content]"></ng-content> </div> <ng-container *ngIf="!ref.hasChildNodes()"> <div>Default value</div> &l ...

How can I implement email authentication in Angular using Firebase?

After only a month of playing around with Angular, I have managed to develop a web app with login and signup forms using Firebase for data storage and authentication. Typically, new users are required to sign up before logging in. However, I now face a di ...

Obtain the input value from a modal and receive an empty string if no value

Utilizing ng-multiselect-dropdown within my bootstrap modal allows users to choose multiple products. Each time an item is selected (onItemSelect), a new div is inserted using the jQuery method insertAfter(). This new div displays the quantity of the selec ...

How can I retrieve routing parameters in a Vue.js/Nuxt/TypeScript app?

In the process of developing my website based on the Nuxt TypeScript Starter template, I've encountered a challenge. Specifically, I have created a dynamically routed page named _id.vue within my pages folder and am looking to access the id property i ...

Issue with the proper functionality of the this.formGroup.updateValueAndValidity() method in Angular 6

Currently, I am facing an issue where I need to add or remove validators in a formGroup's controls based on certain conditions. When I try to update the validators using `formGroup.updateValueAndValidity()` for the entire form, it does not seem to wor ...

Why does Angular2 Router3 not call the Parent Route's Guard every time I navigate between its child routes?

My parent route has a Guard that should be called whenever navigating between child routes. However, I'm facing an issue where the Guard is only triggered when the first child is loaded and not on subsequent switches to other children within the same ...

What is the best way to create a TypeScript function similar to a 'map' in React?

I recently started learning TS and am having trouble typing this arrow function: const mapLikeGet = (obj, key) => { if (Object.prototype.hasOwnProperty.call(obj, key)) return obj[key] } ...

Exploring the process of linking a C# REST API to an Ionic 2 mobile application

I am completely lost on how to connect an asp.net web api with my ionic 2 mobile app. Any help or advice on resolving this problem would be greatly valued! ...

PageObjectModel Playwright, execute the locator().all() function - 'The execution context has been terminated, possibly due to navigating to another...'

Hey there, I'm currently working on a basic test using POM. Here is a snippet from one of my PageObjects Class: import { Expect, Page, Locator } from "@playwright/test"; export class InventoryPage { readonly page: Page; readonly addToC ...

DOCKER: Encounter with MongooseError [MongooseServerSelectionError] - Unable to resolve address for mongo

I am currently attempting to establish a connection between MongoDB and my application within a Docker container. Utilizing the mongoose package, here is the code snippet that I have implemented: mongoose.connect("mongodb://mongo:27016/IssueTracker", { us ...

Angular4: Automatically disable button after it is clicked within ngFor loop

I am facing the issue of disabling a <button> in an ngFor loop after it has been clicked by the user. Each button corresponds to an element in the loop, so I need to distinguish them using separate boolean values. Below is a snippet of the HTML code ...

What is the reason that Gatsby's arrow function is unable to access a value from props that is calculated from a promise?

Could someone shed light on why the key value is showing as undefined within the arrow function: // in parent component const Parent = () => { const [key, setKey] = useState<string>(); // this contains an expensive function we on ...

Validation Form Controls

Here is a piece of code that works for me: this.BridgeForm = this.formBuilder.group({ gateway: ["", [Validators.required, Validators.pattern(this.ipRegex)]], }); However, I would like to provide more detail about the properties: this.BridgeF ...

Navigating product search in your Ionic Ecommerce App

Currently, I am working on developing an Ionic Ecommerce App with a large number of products that need to be displayed. However, I am facing a challenge when it comes to implementing the search functionality for these products within the Ionic App. After c ...

Problems with installing ambient typings

I'm having trouble installing some ambient typings on my machine. After upgrading node, it seems like the typings are no longer being found in the dt location. Here is the error message I am encountering: ~/w/r/c/src (master ⚡☡) typings search mo ...

What is preventing me from adjusting the padding of the mat-button?

Trying to adjust the default padding of a mat-button, but encountering issues with changing the component's style. Any suggestions on how to subscribe to the default padding (16px)? I've attempted modifying CSS properties to set the padding of a ...

Modify animation trigger when mouse hovers over

I am looking to create a feature where a slide overlay appears from the bottom of a thumbnail when the user hovers over it, and retracts when the user is not hovering. animations: [ trigger('overlaySlide', [ state(&ap ...

Leveraging Javascript Modules within a Typescript Vue Application

The issue at hand I've encountered a problem while attempting to integrate https://github.com/moonwave99/fretboard.js into my Vue project. My initial approach involved importing the module into a component as shown below: <template> <div&g ...

Associate text with a color from a predetermined list (JavaScript)

As I work on adding tags to my website for blog posts, I have a specific vision in mind. Each tag should be assigned a unique background color selected from a predefined array of theme colors. My goal is to assign the same background color to tags with id ...