Reputation: 91
I used to load and render my components by its name with a service using ComponentFactoryResolver.
This is a part of the code, the one which renders the component
//Get the Type of the component by its string's name
const type: Type<any> = await this.getTypeOfComponent(component);
//Call the factory for create the component
const componentFactory = this.componentFactoryResolver.resolveComponentFactory(type);
const componentRef = componentFactory.create(new DialogInjector(this.injector, data));
this.appRef.attachView(componentRef.hostView);
//Attach the component
const domElem = (componentRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
document.querySelector('.flyout').firstChild.appendChild(domElem);
this.dialogComponentRef = componentRef;
return homeRef;
And I got the Type of the component using two lines in the function getTypeOfComponent:
let factories = Array.from(this.componentFactoryResolver['_factories'].values());
let factoryClass: any = factories.find((x: any) => x.componentType.name === component);
return factoryClass.componentType;
I've read in Angular 9 with Ivy, you have to import the component for 'lazy loading' and render a component.
Using for example
this.foo = import(`./foo/foo.component`)
.then(({ FooComponent }) => FooComponent);
But I'm unable of doing this, I'm always getting the same error which is
core.js:5845 ERROR Error: Uncaught (in promise): Error: Cannot find module 'details-products/details-products.component' Error: Cannot find module 'details-products/details-products.component'
I've tried with a lot of paths to the component and still getting the same error.
Any ideas? Any other ways of rendering a component in Angular 9 with Ivy?
EDIT:
I've tried an import like the blogs said. For example:
import('src/app/my-component.ts')
That'll work for me, BUT if I do the next:
let src = 'src/app/my-component.ts';
import(src);
Then this won't work and throws the error of can't find the module.
Any ideas?
Upvotes: 2
Views: 2317
Reputation: 1
I solved my problem using this way.
const factories = Array.from(this.resolver['ngModule'].instance.constructor.ɵmod.declarations);
const factoryClass = <Type<any>>factories.find((x: any) => x.name === 'your_component_name');
Upvotes: 0
Reputation: 11
I solved my problem with a ugly way. But I believe that will helps you until find a better solution:
const object = Array.from(this.componentFactoryResolver['ngModule'].instance.constructor.decorators.values())[0]['args'][0];
const factories = object.declarations.concat(object.entryComponents, object.imports, object.providers);
// const factories = Array.from(this.componentFactoryResolver['_factories'].keys());
const factoryClass = < Type<any> > factories.find((x: any) => x.name === your_component_name);
const factory = this.componentFactoryResolver.resolveComponentFactory(factoryClass);
//
const ref = this.dialogService.open(factory.componentType, {
header: your_component_name,
});
Upvotes: 1