HTML injection in Angular

89 Views Asked by At

I have to transform this code in order to use it for html injection in an Angular app (in this way it doesn't load any css or animations).

dataService.getThings().subscribe(
(data) => {
  const list = document.getElementById("nav-list");
  data.forEach((element: any) => {

    let actions = ``;
    Object.entries(element.actions).forEach((action: any) => {
      actions += `<button mat-button>${action[0]}</button>`;
    });

    let properties = ``;
    Object.entries(element.properties).forEach((property: any) => {
      properties += `<button mat-button>${property[0]}</button>`;
    });

    let thingExp = `<mat-expansion-panel>
                      <mat-expansion-panel-header>
                        ${element.title}
                      </mat-expansion-panel-header>
                      <ng-template matExpansionPanelContent>
                        ${actions}${properties}
                      </ng-template>
                    </mat-expansion-panel>`

    list!.innerHTML += thingExp;
  });
}

How can i do it?

3

There are 3 best solutions below

0
simonetassi On BEST ANSWER

After trying to sanitize my html, the best solution, as suggested by Volkan Talayhan in the comments was to use Angular Dynamic Components.

This is the html part for the component:

<mat-expansion-panel *ngFor="let element of data" class="panel" [attr.id]="element.id">
<mat-expansion-panel-header>
    {{ element.title }}
</mat-expansion-panel-header>
<ng-template matExpansionPanelContent class="btn-container">
    <button mat-button class="thing-btn" (click)="onAddThingNode(element.title, element.id)">{{ element.title }}</button>
    <button mat-button *ngFor="let action of getObjectKeys(element.actions)" class="action-btn"
        (click)="onAddActionNode(action, element.id)">{{ action }}</button>
    <button mat-button *ngFor="let property of getObjectKeys(element.properties)" class="property-btn"
        (click)="onAddPropertyNode(property, element.id)">{{ property }}</button>
</ng-template>
2
Volkan Talayhan On
  • Add a new pipe file into your project "SafeHtml.pipe.ts"

  • Add "SafeHtml.pipe.ts to declarations in your app.module

  • define a new string variable in your component.ts file first (forexample htmlContent='';)

  • Replace list.innerHTML += thingExp; with this.htmlContent+=thingExp;

  • in your component.html use <div [innerHtml]="htmlContent | safeHtml">

     //SafeHtml.pipe.ts
     import { Pipe ,PipeTransform} from '@angular/core';
     import {DomSanitizer} from '@angular/platform-browser';
     @Pipe({name: 'safeHtml'})
     export class SafeHtmlPipe implements PipeTransform {
     constructor(private sanitizer: DomSanitizer){}
    
      transform(html: string) {
         return this.sanitizer.bypassSecurityTrustHtml(html);
      }
    }
    
0
Stalky On

Can try to make html trusted code directly, without create a pipe. add an imnport

import { DomSanitizer } from "@angular/platform-browser";

inject the service in constructor

  constructor(
  ...,
    private sanitizer: DomSanitizer,
   ...
  ) { }

use it when set the innerHTML of element (rewrite the line of your code)

list!.innerHTML += this.sanitizer.bypassSecurityTrustHtml(thingExp);