I'm currently working on an Angular application. In one of my methods, I dynamically create a component, however I am unable to use ngClass, ngIf and other such directives from the CommonModule in the component.
Below is an example of the error:
Error when I use ngIf or ngClass inside the dynamically loaded logo component
WHAT I DID ALREADY:
- I've imported commonModule in my project app.module.ts
- I've imported commonModule in my display component and it works as I'm able to use ngIf and ngClass in every other component without any problem
- Also I'm able to import any component without errors as long as I'm not using any directive from the CommonModule in my html
- I've tried importing an instance of the NgModule through component factory createComponent function as shown in the angular documentation:
Quick view of angular documentation on component factory createcomponent
I have spent hours on this and believe it's related to my use of the createComponent method.
Please Help!
Here's my app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule, HammerGestureConfig, HammerModule,
HAMMER_GESTURE_CONFIG } from '@angular/platform-browser';
import { GoogleAnalyticsService } from
'./shared/services/googleanalytics'; // import our Google Analytics
service
import { BrowserAnimationsModule } from '@angular/platform-
browser/animations';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { CommonModule } from '@angular/common';
@NgModule({
declarations: [AppComponent],
imports: [
CommonModule,
BrowserModule,
AppRoutingModule,
HttpClientModule,
BrowserAnimationsModule,
],
providers: [GoogleAnalyticsService],
bootstrap: [AppComponent],
})
export class AppModule {}
Here's my Display component (Bdoc-a.component.ts)
import {
Component, OnInit, Input, Output, Renderer2, AfterViewInit,
AfterContentChecked, ViewChild, ElementRef,
ComponentFactoryResolver, ViewContainerRef, ViewChildren, QueryList
} from '@angular/core';
import { StorageService } from
'../../../../shared/services/storage.service';
import { AuthService } from '../../../../auth/auth.service';
@Component({
selector: 'app-bdoc-a',
templateUrl: './bdoc-a.component.html',
styleUrls: ['./bdoc-a.component.scss'],
})
export class BdocAComponent implements OnInit, AfterViewInit,
AfterContentChecked {
@Input() docConfig = { aspectRatio: '4:3', width: 800, height: 500 };
@Input() bgStyles = { shadow: true, bgClr: '#ffcc00' };
@Input() showBtns = false;
fWidth = this.docConfig.width;
fMaxWidth = this.docConfig.width;
fHeight = this.docConfig.height;
fMaxHeight = this.docConfig.height;
@Input() url = '';
@Input() settings = { ... };
...
@ViewChildren('loadDynAssetElEditItms', { read: ViewContainerRef })
biEditEls: QueryList<ViewContainerRef>;
@ViewChildren('loadDynAssetElViewItms', { read: ViewContainerRef })
biViewEls: QueryList<ViewContainerRef>;
loadDynAssetEl: any;
@ViewChild('bieditorFloat', { read: ElementRef }) bieditorFloat:
ElementRef;
@ViewChild('bieditorFloatViewer', { read: ElementRef })
bieditorFloatViewer: ElementRef;
// variable to hold all document page elements
allDocPages: any;
allDocPageComp = [];
constructor(private storage: StorageService,
private resolver: ComponentFactoryResolver,
private authService: AuthService,
private elmRef: ElementRef) {
this.url = 'templates/logo/1/logo1a/logo1a.component';
}
ngAfterViewInit(): void {
this.initBrandAsset();
}
initBrandAsset(): void {
this.allDocPageComp = [];
setTimeout(() => {
for (let i = 0; i < this.pages; i++) {
this.loadDynAsset(this.url, i);
}
this.setDocPageVar();
}, 200);
}
async loadDynAsset(url, pgIndex) {
const impEl = await import( 'src/app/' + url);
const allKeys = Object.keys(impEl);
this.biEditEls.forEach((itm, i) => {
if (i === pgIndex) {
itm.clear();
const newComp = itm.createComponent(
this.resolver.resolveComponentFactory(impEl[allKeys[0]]));
newComp.instance['bol']['test'] = 'LOGO TEST TEXT HERE... ' + pgIndex;
this.allDocPageComp.push(newComp.instance);
}
});
}
}
Here's my Logo1a.component.html
<div class="baItem biLogo logo1a edit">
<div class="null bilNull">
<ng-container>
<div class="bilSymb">
<div class="null">
<div #forTxtLogo class="forTxtLogo" *ngIf="config.symb.mode ===
'txt'">
<div class="symbItm"><div class="nl">B</div></div><div
class="symbItm"><div class="nl">S</div></div>
</div>
<div #forImgSvgLogo class="forImgSvgLogo" *ngIf="config.symb.mode
=== 'svg' || config.symb.mode === 'img'">
<div class="symbItm"><div class="nl"></div></div>
</div>
</div>
</div><!-- end of bilSymb -->
</ng-container>
<ng-container *ngIf="config.body.show">
<div class="bilBody">
<div class="null">
<ng-container *ngIf="config.body.txt.show">
<div #forTxtArea class="forTxtArea">
<div class="null">Logo Body Text Area</div>
</div>
</ng-container>
<ng-container *ngIf="config.body.tag.show">
<div #forTagArea class="forTagArea"><div class="null">Logo Tag
Area...</div></div>
</ng-container>
</div>
</div><!-- end of bilBody -->
</ng-container>
</div><!-- end of biNull -->
</div><!-- end of biLogo-->
Here's my Logo1a.component.ts
import { NgModule, Component, OnInit, Input, Output, Renderer2,
AfterViewInit, AfterContentChecked, ViewChild, ElementRef,
ComponentFactoryResolver, ViewContainerRef, ViewChildren, QueryList
} from '@angular/core';
import { StorageService } from
'../../../../shared/services/storage.service';
import { AuthService } from '../../../../auth/auth.service';
@Component({
selector: "app-logo1a",
templateUrl: "./logo1a.component.html",
styleUrls: ["./logo1a.component.scss"],
})
export class Logo1aComponent implements OnInit, AfterViewInit {
@ViewChild('loadExtra', { read: ViewContainerRef }) loadExtra:
ViewContainerRef;
@Input() bol = { test: 'LOGO 1A LOADED!' }; // breadth of life
public config = {
symb: {
show: true,
mode: 'txt', // 'txt', 'symb', 'img'
},
body: {
show: true,
txt: { show: true },
tag: { show: true }
}
}
constructor(private storage: StorageService,
private resolver: ComponentFactoryResolver,
private vcRef: ViewContainerRef,
private authService: AuthService,
private elmRef: ElementRef) { }
ngOnInit(): void {}
ngAfterViewInit() {}
}
Here's my Logo1a.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Logo1aComponent } from './logo1a.component';
@NgModule({
imports: [CommonModule],
declarations: [Logo1aComponent],
exports: [Logo1aComponent]
})
export class Logo1aModule {}
But this was the error that was thrown after I dynamically imported the module instead of the component in my Angular 10 app as @jburtondev suggested:
ERROR Error: Uncaught (in promise): Error: ASSERTION ERROR: Type passed in is not ComponentType, it does not have 'ɵcmp' property. ....