Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Load post request into an iframe in angular2

I have a webservice that generates HTML with inline CSS for HTML emails in response to a POST requests at the following URL: https://civinky.3sd.io/generate

I have built a simple angular2 app here http://civinky-demo.3sd.io/ so people can see the HTML that will be produced. The idea is that you add the params on the left hand side and hit the button. Angular makes a post request and displays the a result on the right hand side. A preview of the generated HTML in an iframe and the raw html in a div underneath.

Here is the service:

import { Injectable } from '@angular/core';
import { Http, URLSearchParams }          from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';

@Injectable()
export class CivinkyService {

  url ="https://civinky.3sd.io/generate"

  constructor(private http: Http, private elementRef: ElementRef) { }

  query(pug, css, json) {
    let params = new URLSearchParams()
    params.append('pug', pug)
    params.append('css', css)
    params.append('json', json)
    let body = params.toString()
    let result = this.http.post(this.url, body)
      .map(res => {return {url:res.url,html:res.text().trim()}})
    return result;
  }
}

That I am querying from my component

import { Component, OnInit } from '@angular/core';
import { Observable }       from 'rxjs/Observable';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
import { CivinkyService } from '../civinky.service';


@Component({
  selector: 'app-civinky',
  templateUrl: 'civinky.component.html',
  styleUrls: ['civinky.component.css'],
  providers: [CivinkyService]
  // encapsulation: ViewEncapsulation.None,

})
export class CivinkyComponent implements OnInit {


  url: SafeResourceUrl

  urlString: string

  html: string

  pug: string = `some pug`

  css: string = `some css`

  json: string = `some json`

  constructor(
    private civinky: CivinkyService,
    private sanitizer: DomSanitizer
  ) { }

  ngOnInit() {
    this.queryCivinky()
  }

  queryCivinky() {
    this.civinky.query(this.pug, this.css, this.json).subscribe(
      result => {
        this.html = result.html
        this.url = this.url = this.sanitizer.bypassSecurityTrustResourceUrl(result.url)
      }
    )
  }
}

Revelant snippet of the template

<iframe [attr.src]="url"></iframe> <!-- preview -->
<textarea [(ngModel)]="html" readonly></textarea> <!-- raw -->

What I can't work out how to do is preview it in the iframe. I would be happy to either ask the iframe to POST the request or to inject the {{html}} as content of the iframe but I can't work out how to do either.

The angular2 app source is here: https://github.com/3sd/civinky-demo

Help appreciated :)

like image 698
michaelmcandrew Avatar asked Jun 26 '17 19:06

michaelmcandrew


2 Answers

You can use DomSanitizer from platform-browser module

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

Inject DomSanitizer in your component by initializing it in your constructor

  constructor(private domSanitizer: DomSanitizer)

use bypassSecurityTrustHtml() of DomSanitizer and pass your raw html received from http response ::

this.displayString= this.domSanitizer.bypassSecurityTrustHtml("<div>html text received from api</div>");

use it in your html like this:

 <iframe [srcdoc]="displayString"></iframe>

I hope this will solve your problem.

like image 81
Deepak Kumar Avatar answered Nov 04 '22 09:11

Deepak Kumar


You could use srcdoc, SafeHtml and bypassSecurityTrustHtml

import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
...

export class CivinkyComponent implements OnInit {    
  htmlSrc: SafeHtml 
  html: string
  ...
}

queryCivinky() {
   this.civinky.query(this.pug, this.css, this.json).subscribe(
      result => {
        this.htmlSrc = this.sanitizer.bypassSecurityTrustHtml(result.html)
        this.html = result.html
      }
   )
}

And for the iframe:

<iframe [srcdoc]="htmlSrc"></iframe>

Credit: https://stackoverflow.com/a/38852423/1544886

like image 20
K Scandrett Avatar answered Nov 04 '22 09:11

K Scandrett