8

I got a serie of html in my server. For example:

And I trying to include those files into a<div> in my angular2 v4 app. For example:

component.ts

public changePage(name: string) {
  switch (name) {
    case 'intro': this.myHtmlTemplate = 'http://docs.example.com/intro.html'; break;
    case 'page1': this.myHtmlTemplate = 'http://docs.example.com/page1.html'; break;
    case 'page2': this.myHtmlTemplate = 'http://docs.example.com/page2.html'; break;
  }
}

component.html

<div [innerHtml]="myHtmlTemplate"></div>

but it doesnt work. I tried the following solutions:

Angular4 Load external html page in a div

Dynamically load HTML template in angular2

but it doesn't work for me. Can somebody help me with this problem please ?

Sergio Mendez
  • 1,311
  • 8
  • 33
  • 56
  • 1
    This is not at how you should be doing this. Look at https://www.concretepage.com/angular-2/angular-4-ng-template-example#ngSwitch – msanford Jun 11 '19 at 20:10
  • Thanks @msanford But I'm looking for a solution where the html templates are on a different server than the angular application and only imported through the link. The html templates must be independent of the application in angular. – Sergio Mendez Jun 11 '19 at 20:18

5 Answers5

12

Angular security Blocks dynamic rendering of HTML and other scripts. You need to bypass them using DOM Sanitizer.

Read more here : Angular Security

DO below changes in your code :

// in your component.ts file

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


// in constructor create object 

constructor( 
...
private sanitizer: DomSanitizer

...
){

}

someMethod(){

  const headers = new HttpHeaders({
  'Content-Type':  'text/plain',
});
const request = this.http.get<string>('https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Your_first_HTML_form', {
  headers: headers,
  responseType: 'text'
}).subscribe(res => this.htmlString = res);

 this.htmlData = this.sanitizer.bypassSecurityTrustHtml(this.htmlString); // this line bypasses angular security

}

and in HTML file ;

<!-- In Your html file-->
    <div [innerHtml]="htmlData">
    </div>

Here is the working example of your requirement :

Working Stackblitz Demo

programoholic
  • 4,830
  • 5
  • 20
  • 59
  • I like your solution. Unfortunately it doesn't work for all .html files. Even in the stackblitz demo, returns console errors. If you have another solution in any other way (except an iframe), I would like to know. Thank you – Sergio Mendez Jun 17 '19 at 18:52
  • @SergioMendez that is because the website didn't send the html response (may be due to cross origin request). If you have list of the websites which returns the html content. The above solution will definitely work. – programoholic Jun 18 '19 at 07:29
  • 1
    Thank you very much. You Really helpme to find the solution. – Sergio Mendez Jun 18 '19 at 15:16
1

This should do it:

First in your component.ts get the html with a http request:

import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map } from 'rxjs/operators'

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {

  constructor(private http: HttpClient) { }

  htmlString: string;

  ngOnInit() {
    const headers = new HttpHeaders({
      'Content-Type':  'text/plain',
    });
    const request = this.http.get<string>('https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Your_first_HTML_form', {
      headers: headers,
      responseType: 'text'
    }).subscribe(res => this.htmlString = res);
  }

}

And in your component.html simply use a one way data binding:

<div [innerHTML]="htmlString"></div> 
Marcel
  • 127
  • 7
  • Sure I tried. Then the "responseType: 'text'" returns the following error: Type '"text"' is not assignable to type '"json"'.ts(2322) client.d.ts(639, 9): The expected type comes from property 'responseType' which is declared here on type ... – Sergio Mendez Jun 11 '19 at 21:24
  • you have to set "responseType: 'text' as 'json'" to fool the typescript transpiler – Marco Dec 08 '20 at 08:49
0

You actually want to display a page inside your angular app right?

For that you can add a iframe tag:

<iframe width="400" height="600" [src]="myHtmlTemplate"></iframe>
ahbon
  • 502
  • 4
  • 19
  • thank you very much, I'm avoiding the – Sergio Mendez Jun 11 '19 at 20:31
0

In your component first request pages with HTTP request

this.http.get('http://docs.example.com/intro.html').map(response => response.text()).subscribe(html => Your_template = html);

use innerhtml with the safehtml pipe so your inline styling will be applied more info on GitHub page(https://gist.github.com/klihelp/4dcac910124409fa7bd20f230818c8d1)

<div [innerHtml]="Your_template | safeHtml"></div>
NickCoder
  • 1,504
  • 2
  • 23
  • 35
0

you have to get HTTP call to load HTML in plain text and load in div using innerHtml.

export class AppComponent implements OnInit {
name = 'Kissht';
KisshtHtml;
constructor(
 private http:HttpClient,
 private sanitizer:DomSanitizer){ }
ngOnInit(){
   this.http.get('https://kissht.com/', 
  {responseType:'text'}).subscribe(res=>{
    this.KisshtHtml = this.sanitizer.bypassSecurityTrustHtml(res);
  })
 }
}

Sometime you might get CORS issue in stackblitz whil loading external Html

https://stackblitz.com/edit/display-external-html-into-angular