0

I am getting one html page as response from an API call. I want to show it to the frontend side. What would be the best possible way I can do?

I have used httpClient request to get the data and iframe to show it and it works fine with me,but I want to show the data in whole new HTML page.

  @ViewChild("iframe", { static: true }) iframe: ElementRef;
  //getting the iframe references from the html

  //From service
  getDataSummary() {
  return this._http.get(this.dataSummaryUrl, { responseType: "text" });
  }



  //Component ts file code
  onClickDataSummary() {
  this.fileUploadService.getDataSummary().subscribe(
    data => {
      let doc =
        this.iframe.nativeElement.contentDocument ||
        this.iframe.nativeElement.contentWindow;
      doc.open();
      doc.write(data);
      doc.close();
      this.dataSummaryLoading = false;
      this.dataSummaryDiv = true;
      this.showLoader = false;
    },
    error => {
      alert(` ${error.statusText} occurred!! Please check server side`);
      this.dataSummaryLoading = false;
      this.dataSummaryDiv = true;
      this.showLoader = false;
    }
  );
}
}

The HTML code would be like this -

 <mat-tab label="Data Summary">
  <mat-toolbar color="">
    <span>Data Summary</span>
    <span class="example-fill-remaining-space"></span>
    <span
      ><button
        mat-raised-button
        class=" mb-2"
        color="primary"
        (click)="onClickDataSummary()"
        *ngIf="!dataSummaryLoading"
      >
        Data Summary
      </button></span
    >
    <button
      class=" mb-2"
      mat-raised-button
      color="primary"
      *ngIf="dataSummaryLoading"
    >
      <span class="spinner-border spinner-border-sm "></span>
      Loading
    </button>
  </mat-toolbar>
  <div
    class="example-container mat-elevation-z8"
    [class.hide]="!dataSummaryDiv"
  >
    <iframe width="100%" height="100%" #iframe></iframe>
  </div>
  <div class="text-center m-5" [class.hide]="!showLoader">
    <app-loader></app-loader>
  </div>
</mat-tab>

Expected output would be to get the html page when click on a button. like here on clicking of Data Summary not in iFrame.

Thanks is advance for your time here.

Srinivasan Sekar
  • 2,049
  • 13
  • 22
Souradip
  • 111
  • 1
  • 10
  • do you want to open the html page in new window or want to display on same page – jitender Oct 16 '19 at 04:04
  • Well you can create a new Angular component that uses the html page as template. You can then route your API call to the new component using Angular routing. See this link: https://angular.io/guide/router – Nadir Latif Oct 16 '19 at 04:04
  • @jitender what would be the options for both in new window and on same page? – Souradip Oct 16 '19 at 04:08
  • @NadirLatif - I did not get your point. How I could store the html page coming from api call and store into an component template? – Souradip Oct 16 '19 at 04:10
  • this may help https://stackoverflow.com/a/46660076/5621827 to display in same window – jitender Oct 16 '19 at 04:12
  • @Souradip, If the html text is known, then you can set it as a html template for a component. But if the html page is coming from an API call, then you can set the innerHTML property of a element to the html text – Nadir Latif Oct 16 '19 at 04:17

2 Answers2

0

Change

let doc =
    this.iframe.nativeElement.contentDocument ||
    this.iframe.nativeElement.contentWindow;

to

let newWindow = window.open();

let doc = newWindow.document;
Adrian Brand
  • 20,384
  • 4
  • 39
  • 60
0

In most cases, the HTML response should have the same header and footer and we just [innerHTML] it. But if you want to open it as a separate page then you have to use native javascript for it.

const html = '<html><head></head><body>Hello</body></html>';
const uri = "data:text/html," + encodeURIComponent(html);
const newWindow = window.open(uri);

You can custom the window.open according to your preferences.

And if you want to use a different layout for this type of responses then you can check this out.

multiple layouts for different pages

sibabrat swain
  • 1,277
  • 8
  • 20