Angular 8 return HTML from rendered component

1.7k views Asked by At

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?

0

There are 0 answers