Components inside iframe (and data binding) in Angular

Sk Asik
The Startup
Published in
2 min readMay 6, 2020

Render components inside an iframe present in a template

Photo by Maxwell Nelson on Unsplash

After a recent brush with an iframe related issue I decided to put some of my learnings into an edit. In this article, I’m assuming that you already have some basic understanding of Angular.

Lets say we have a component, InnerComponent, that takes an input, firstInput, and has an emitter, emitOutput. Normally we would be using something like

<app-inner [firstInput]=”firstInputData” (emitOutput)=”emitOutputHandler($event)”></app-inner>

I was tasked to bind a component like this inside an iframe present in another component’s html template.

The first step is adding an iframe:

<iframe style=”height: 500px; width: 100%;” #iframe (load)=”onLoad(iframe)”></iframe>

And creating the reference to the iframe inside the ts file and creating references for the component that needs to be embedded inside the iframe, using ComponentRef.

@ViewChild(‘iframe’, {static: false}) iframe: ElementRef;firstInput = 5;
doc;
compRef: ComponentRef<InnerComponent>;

Now when the iframe loads in out view we need to capture the content document of the iframe. The on-load trigger in the iframe tag calls the necessary code for this.

onLoad(iframe){this.doc = iframe.contentDocument || iframe.contentWindow;this.createComponent();}

The createComponent methods does the remaining:

createComponent() {const compFactory = this.resolver.resolveComponentFactory(InnerComponent);this.compRef = this.vcRef.createComponent(compFactory);this.compRef.location.nativeElement.id = ‘innerComp’;
(<InnerComponent>this.compRef.instance).firstInput = this.firstInput;(<InnerComponent>this.compRef.instance).emitOutput.subscribe(response => {console.log(response);});this.doc.body.appendChild(this.compRef.location.nativeElement);}

Data binding is done by using the instance property and both Input and Output emitters can be handled accordingly. This way even while inside an iframe the angular application is able to reference its components.

Remember to add the imports to ViewContainerRef and ComponentFactoryResolver in the constructor

constructor(private vcRef: ViewContainerRef, private resolver: ComponentFactoryResolver) { }

Check out the gist for the whole file

Thanks for reading. Yes, this is my first article, and thanks again for sticking by until the end!

--

--

Sk Asik
The Startup

I am Sk Asik and I’m a software developer. I am young into my career, constantly learning and hoping to share.