Search code examples
htmlangularinnerhtml

Angular - Render HTML inside <p> tag


I want to render some html table and some data inside a <p> tag in Angular

In my report.component.html

<div class="ui-g-12">
  <div class="ui-g-12" *ngFor="let item of items">
    <p-fieldset legend="{{item.recordTime}}" [toggleable]="true" [collapsed]="true">
      <div class="overflow">
        <p [innerHTML]="item.message"></p>
      </div>
    </p-fieldset>
  </div>
</div>

In my report.component.ts

ngOnInit() {
  this.listAllReports();
}

  listAllReports() {
    this.httpSvc.fetchWithoutSpinner(this.urlBuilder.getAllReportUrl()).subscribe(data => {
      data.forEach(report => {
        const newReport= new Report();
        newReport.message = '<table style="font-family: arial, sans-serif; border-collapse: collapse; width: 100%;"> <tr> <th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Item1</th> <th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Item2</th> <th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Item3</th> <th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Item4</th> <th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Item5</th> <th style="border: 1px solid #dddddd; text-align: left; padding: 8px;">Item6</th> </tr><tr> <td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">238342</td><td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">000</td><td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">807</td><td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">ZZZZ</td><td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">XXX</td><td style="border: 1px solid #dddddd; text-align: left; padding: 8px;">YYY</td></tr></table>';
        newReport.recordTime = report.recordTime;
        this.items.push(newReport);
      });
    });
  }

Note that in the newReport.message, inside has some html codes that should be rendered.

But the table is not rendered:

enter image description here

Where is my mistakes?


Solution

  • Use a custom Angular pipe to bypass the security for the html.

    Your HTML will be like this

    <div [innerHTML]="item.message | TrustHtml"></div>
    

    And the Pipe will be as follows

    import { Pipe, PipeTransform } from '@angular/core';
    import { DomSanitizer } from '@angular/platform-browser';
    
    @Pipe({
        name: 'TrustHtml',
        pure: true // This allows the pipe to only run once
    })
    export class TrustHtmlPipe implements PipeTransform {
    
        constructor(private sanitizer: DomSanitizer) {
        }
    
        transform(pUnsafe: string) {
            return this.sanitizer.bypassSecurityTrustHtml(pUnsafe);
        }
    }