The common use case for compiling Angular components into HTML strings are
Unfortunately Angular doesn’t have an exposed method to compile an Angular component into an HTML string. But thanks to Angular’s ComponentFactoryResolver
, we can create a workaround for this. Using ComponentFactoryResolver
, we can dynamically render the required component into a template, and then we access the nativeElement.innerHTML
from componentRef
.
One thing to note here is we have used import { asyncScheduler } from 'rxjs';
for getting HTML with all the bindings. If we are not setting this scheduler, no data binding will be available in the parse HTML.
import {
Component,
ComponentFactory,
ComponentFactoryResolver,
ViewChild,
ViewContainerRef,
} from '@angular/core';
import { asyncScheduler } from 'rxjs';
import { PdfHtmlComponent } from './pdf-html.component';
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
@ViewChild('pdfHtml', { read: ViewContainerRef }) container;
constructor(private resolver: ComponentFactoryResolver) {}
getPDFHtml() {
this.container.clear();
const factory: ComponentFactory<any> =
this.resolver.resolveComponentFactory(PdfHtmlComponent);
const componentRef = this.container.createComponent(factory);
componentRef.instance.title = 'Injected Title';
asyncScheduler.schedule(() => {
const htmlString = componentRef.location.nativeElement.innerHTML;
componentRef.destroy();
console.log('HTML STRING:', htmlString);
});
}
}
<button (click)="getPDFHtml()">CLICK TO GET COMPONENT HTML</button>
<p>Output is in the console</p>
<div [hidden]="true">
<template #pdfHtml></template>
</div>
import { Component } from '@angular/core';
@Component({
selector: 'pdf-html',
templateUrl: './pdf-html.component.html',
})
export class PdfHtmlComponent {
title: string = 'Default Title';
STYLES: any = {
MAIN_CONTAINER: 'background:red;',
ITEM_BOX: 'color:red;',
};
}
<h2>Title: {{ title }}</h2>
<table style="{{ STYLES.MAIN_CONTAINER }}">
<tr style="{{ STYLES.ITEM_BOX }}">
<th>Company</th>
<th>Contact</th>
<th>Country</th>
</tr>
<tr style="{{ STYLES.ITEM_BOX }}">
<td>Alfreds Futterkiste</td>
<td>Maria Anders</td>
<td>Germany</td>
</tr>
<tr style="{{ STYLES.ITEM_BOX }}">
<td>Centro comercial Moctezuma</td>
<td>Francisco Chang</td>
<td>Mexico</td>
</tr>
<tr style="{{ STYLES.ITEM_BOX }}">
<td>Ernst Handel</td>
<td>Roland Mendel</td>
<td>Austria</td>
</tr>
</table>
You can see the demo here
or you can play with the code here
Happy coding!!! 🎉🎉🎉