I want to dynamically generate a component to extract it's HTML, return it from a function and pass it as [innerHTML] to maintain page-texts with HTML-content.
To achieve that I wrote a service to generate the component, pass in parameters, detect changes and return it's html:
public showText(notation: string, variables: object = {}) {
const cmpRef: ComponentRef<TextComponent> = this.textFactory.create(this.injector);
cmpRef.instance.isAdmin = this.isAdmin
cmpRef.instance.textNotation = notation;
cmpRef.instance.replaceVariables = variables;
cmpRef.hostView.detectChanges();
const textElement = (cmpRef.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
return textElement.innerHTML;
}
The HTML of the TextComponent looks like this:
<ng-container *ngIf="isAdmin">
<a [innerHTML]="textNotation | translate:replaceVariables"></a>
</ng-container>
<ng-container *ngIf="!isAdmin">
<div [innerHTML]="textNotation | translate:replaceVariables"></div>
</ng-container>
And to insert the HTML I call the function like this:
<div [innerHTML]="ts.showTextbrick('text.key')"></div>
Now my Problem:
The text is actually rendered correctly. But I get an errormessage that is hella annoying:
"ERROR Error: "ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked"
Version is Angular 8.
I tried the following to solve it: Inserting changeDetectorRef in TextComponent and call it's detach() function on several lifecycle hooks, for example: ngAfterViewInit, ngOnDestroy, ngOnInit
Calling detach()-function on cmpRef.hostView, calling detach()-function on cmpRef.changeDetectorRef.
The documentation says - for local change detections I shall call .detectChanges()-Function and .detach() afterwards: https://angular.io/api/core/ChangeDetectorRef
did I get that right? Any Ideas?