1

In my Angular RC5 app I used the following code to dynamically load components:

    public LoadComponentAsync(componentPath: string, componentName: string, locationAnchor: ViewContainerRef) {
    (<any>window).System.import(componentPath)
        .then(fileContents => {
            return fileContents[componentName];
        })
        .then(component => {
            this.resolver.resolveComponent(component).then(factory => {
                let comp = locationAnchor.createComponent(factory, 0, locationAnchor.injector).instance;
                //...
            });
        });
}

A component I was loading looked like this:

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

@Component({
    selector: "my-test",
    template: `Test`,
})
export class Main {
    constructor() {
        alert("Test");
    }
}

Since ComponentResolver is depricated, I am looking for a new solution. I could not find one. The most promising solution I found so far:

    loadSubcomponent(modulePath: string, componentName: string) {
    (<any>window).System.import(modulePath)
        .then((module: any) => module[componentName])
        .then((type: any) => {
            return this.compiler.compileModuleAndAllComponentsAsync(type)
        })
        .then((moduleWithFactories: ModuleWithComponentFactories<any>) => {
            const factory = moduleWithFactories.componentFactories.find(x => x.componentType.name === componentName);
            let componentRef = this.extensionAnchor.createComponent(factory, 0);
        });
}

Source: Angular2 RC6 - Dynamically load component from module

Unfortunately, it does not work as I expected. When I call this.loadSubcomponent("/main", "Main"); I get the following error message:

core.umd.js:2834 EXCEPTION: Uncaught (in promise): Error: No NgModule metadata found for Main

Any suggestions?

Community
  • 1
  • 1
Michael
  • 408
  • 3
  • 13

1 Answers1

0

The following does not answer the question completely but it gives a possilbe solution.

The error above happens because we need to load a module and not a single component. By adding @NgModule and declaring the component we can load it as expected.

Here is a small example of a module with a component that can be loaded by calling

this.loadSubcomponent("/main", "Main");

from above:

@NgModule({
declarations: [Main]
})

@Component({
    selector: "my-test",
    template: `Test`,
})
export class Main {
    constructor() {
        alert("Test");
    }
}

It looks like I am not the only one who would like to be able to load only components:

Removal of compileComponentAsync in RC6

Michael
  • 408
  • 3
  • 13
  • For Angular 6: https://stackoverflow.com/questions/50149016/load-new-modules-dynamically-in-run-time-with-angular-cli-angular-5/50395048#50395048 – Michael May 23 '18 at 07:00