1

I've a json file

{
  "articles": [
    {
      "id": 1,
      "title": "<h1>How to install Atom</h1>"
    },
    {
      "id": 2,
      "title": "<h1>Installing Boostrap</h1>"
    }
  ]
}

I am using json-server with angular 8 to read this json. As you can see title field is supposed to be an html head tag when rendered on screen. But it is getting printed as it is. See, this is what I am trying to say. this. I want to convert this into heading-1 tag in run time. My app.component.html is

  <div id="data-container">    
  </div>

  Hello
  <table>
    <tr *ngFor="let art of lstcomments">
      <td>{{art.id}}</td>
      <td>
        document.querySelector('#data-container').innerHTML={{art.title}}
      </td>
    </tr>
  </table>
</div>
<router-outlet></router-outlet>

My title is stored in {{ art.title }}. I tried creating a separate div with id data-container and used document.querySelector but the whole code gets printed as a string. What should I do now.

Tanzeel
  • 4,174
  • 13
  • 57
  • 110

5 Answers5

3

As mentionend in the official docs, Angular automatically sanitize HTML so you can't just put it in the template with a variabile. This is done to prevent different kind of attacks by allowing external actors to interact with your page and push content in your HTML.

For the HTML to be interpreted, you can bind it to the HTML property innerHTML as in this example:

<span [innerHTML]="art.title"></span>

Luca Regazzi
  • 1,345
  • 1
  • 11
  • 23
  • Oh I read the official docs but I think I must have overlooked this. I Upvoted and accepted. Thanks. This worked. – Tanzeel Aug 26 '19 at 19:35
2
  • It's pretty simple. Try the solution below. It is more accurate and safe.
  • In the JSON description when meet SVG image paths or third party anchor URLs are more likely to be broken when they arrive, so we should also use sanitize HTML for its solution.

app.component.html


    <div>
        <!-- <div id="data-container"></div> -->
        <!--Not Needed-->
        Hello
        <table>
            <tr *ngFor="let art of lstcomments">
                <td>{{art?.id}}</td>
                <td>
                    <div [innerHTML]="art?.title | sanitizedHtml"></div>
                    <!-- document.querySelector('#data-container').innerHTML={{art.title}} -->
                    <!--Not Needed-->
                </td>
            </tr>
        </table>
    </div>
    <router-outlet></router-outlet>

sanitized-html.pipe.ts


    import { Pipe, PipeTransform } from '@angular/core';
    import { DomSanitizer } from '@angular/platform-browser'
    @Pipe({
      name: 'sanitizedHtml'
    })
    export class SanitizedHtmlPipe implements PipeTransform {
      constructor(private sanitized: DomSanitizer) {}
      transform(value: any): any {
        return this.sanitized.bypassSecurityTrustHtml(value);
      }
    }

I hope it will be work good. also if you want to know in details for how to import this sanitized pipe then get information from this post

KK Nebula
  • 121
  • 1
  • 2
1

You have to bind the property directly to a variable like this

  <div id="data-container" [innerHTML] ="art.title">

  </div>

and in your controller you have to declare the variable art and then do:

this.art = articles[0] // or articles[1], depending on which article you want

You either do that, or put the container inside the ng-for.

Albondi
  • 1,141
  • 1
  • 8
  • 19
1

Hope you're doing great!!!

You can get the answer from here: Angular 2, DomSanitizer, bypassSecurityTrustHtml, SVG. But, I recommend injecting the DomSanitizer service.

I recommend reading this (https://angular.io/guide/security) from the official docs. All JS Framework behaves exactly like your question is, which is correct!

I recommend reading this (https://angular.io/api/platform-browser/DomSanitizer) as well so that you will never face issues in this area!

Hope I tried to answer your question. Happy Coding! Cheers!!!

Santhosh John
  • 648
  • 5
  • 14
-2

You should use a service to call the server and retrieve the values through the service. Once you do that, inject the service into your component and call the service request to retrieve the JSON response and use a local variable in your component to set the string in your template.

Luke Pinto
  • 27
  • 2
  • I am doing that already. I have `myapi.service.ts` to take care of that. But right now it is irrelevant here. Please read the question properly. – Tanzeel Aug 26 '19 at 19:37