In my setup, there is a component that takes in some data and dynamically generates other components using ngx-charts.
This specific part acts as the directive
@Directive({
selector: '[ad-host]',
})
export class PresentationDirective {
constructor(public viewContainerRef: ViewContainerRef) {
}
}
The template structure is quite straightforward
<div class="presentation">
<ng-template ad-host></ng-template>
</div>
Now moving on to the main component section
presentations: Presentation[] = new Array();
components: any[] = new Array();
During initialization, I iterate through an array of data and execute the loadComponent function
ngOnInit() {
const temp = this.simulationResponse['presentations'];
for (const presentation of temp) {
this.presentations.push(presentation);
this.loadComponent(this.getComponent(presentation['type']),
presentation['data']);
}
}
The getComponent function simply returns the necessary component based on its type to be used by loadComponent
getComponent(componentType: string) {
switch (componentType) {
case 'PIE': {
return PieChartComponent;
}
case 'BAR': {
return BarChartComponent;
}
}
}
Within loadComponent, a new component is created each time it's called with the respective data needed for graphic rendering
loadComponent(component: any, data: any) {
const componentFactory =
this.componentFactoryResolver.resolveComponentFactory(component);
const viewContainerRef = this.adHost.viewContainerRef;
const componentRef =
viewContainerRef.createComponent(componentFactory);
this.components.push(componentRef);
(<AddData>componentRef.instance).single = data;
}
Whenever there are changes in the data, updatePresentations function is triggered
ngOnChanges() {
this.updatePresentations();
}
The struggle arises within updatePresentations, specifically when trying to assign data, resulting in two errors
updatePresentations() {
const viewContainerRef = this.adHost.viewContainerRef;
for (let i = 0; i < viewContainerRef.length; i++) {
const componentRef = viewContainerRef.get(i);
const tmp = this.presentations[i];
(<AddData>componentRef.instance).single = tmp['data'];
}
}
The first error pertains to assigning values, while the second one points out a missing property 'includes'
Error message example - ERROR in src/app/simulator/presentation/presentation.component.ts(71,7): >error TS2322: Type '{}' is not assignable to type 'any[]'.
Another error example - Property 'includes' is missing in type '{}'. src/app/simulator/presentation/presentation.component.ts(71,30): error >TS2339: Property 'instance' does not exist on type 'ViewRef'.
The struggle intensifies with the latter error regarding the 'instance' property from ViewRef
Despite efforts and thorough checks, I am unable to resolve this issue. Any insights or assistance would be greatly appreciated.
Additional Reference:
The development process was heavily influenced by this segment of the Angular guide https://angular.io/guide/dynamic-component-loader