Create Component template and Typescript code dynamically.
I am trying to generate the component on the fly, HTTP service call send us HTML template and Typescript code. In this we are able to set HTMl template dynamically but not typescript code, not able to figure out how to set typescript code dynamically.
* Please find below code which renders HTML template based on HTTP call. *
import { HttpClient, HttpClientModule } from "@angular/common/http";
import { Component, ViewChild, ViewContainerRef, Compiler, Injector, NgModule, NgModuleRef, ComponentFactoryResolver, OnInit } from "@angular/core";
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
@ViewChild('vc', { read: ViewContainerRef }) _container: ViewContainerRef;
constructor(private http: HttpClient, private _compiler: Compiler, private componentFactoryResolver: ComponentFactoryResolver,
private _injector: Injector,
private _m: NgModuleRef<any>) {
}
ngOnInit() {
return this.http.get("https://raw.githubusercontent.com/ketan-gote/stackblitz-demo/master/template.txt", { responseType: 'text' }).subscribe((txt: any) => {
console.log(txt);
const tmpCmp = Component({ template: txt, selector: 'abcd' })(class {
});
const tmpModule = NgModule({ imports: [HttpClientModule], declarations: [tmpCmp], entryComponents: [tmpCmp] })(class {
});
this._compiler.compileModuleAsync(tmpModule)
.then((moduleFactory) => {
debugger;
const resolver = moduleFactory.create(this._injector).componentFactoryResolver;
const f = resolver.resolveComponentFactory(tmpCmp);
const cmpRef = f.create(this._injector, [], null, this._m);
this._container.insert(cmpRef.hostView);
})
});
}
}
Here's a working link !
* PROBLEM Now when we are trying to get TS code also as part of response it gives error core.js:12501 ERROR TypeError: Cannot read property '__annotations__' of undefined *
Please find below code which renders TS
import { HttpClient, HttpClientModule } from "@angular/common/http";
import { Component, ViewChild, ViewContainerRef, Compiler, Injector, NgModule, NgModuleRef, ComponentFactoryResolver, OnInit } from "@angular/core";
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
@ViewChild('vc', { read: ViewContainerRef }) _container: ViewContainerRef;
constructor(private http: HttpClient, private _compiler: Compiler, private componentFactoryResolver: ComponentFactoryResolver,
private _injector: Injector,
private _m: NgModuleRef<any>) {
}
ngOnInit() {
return this.http.get("https://raw.githubusercontent.com/ketan-gote/stackblitz-demo/master/ts.txt", { responseType: 'text' }).subscribe((txt: any) => {
console.log(txt);
const tmpCmp = Component({ template: "<h1>HEAD</h1>", selector: 'abcd' })(txt);
const tmpModule = NgModule({ imports: [HttpClientModule], declarations: [tmpCmp], entryComponents: [tmpCmp] })(class {
});
this._compiler.compileModuleAsync(tmpModule)
.then((moduleFactory) => {
debugger;
const resolver = moduleFactory.create(this._injector).componentFactoryResolver;
const f = resolver.resolveComponentFactory(tmpCmp);
const cmpRef = f.create(this._injector, [], null, this._m);
this._container.insert(cmpRef.hostView);
})
});
}
}
Here's is not working code link!