0

I try to get an iframe element that has a dynamic id that is given as as @Input() attribute from an Angular component. I need this because I need to display a list of iframe in the same page, hence the unique id :

What I have tried : https://stackblitz.com/edit/angular-yhdijr

app.component.html :

<div *ngFor="let index of [0, 1, 2]">
  <app-iframe [iframeId]="'iframe' + index"></app-iframe>
</div>

iframe.component.ts :

export class IframeComponent implements OnInit {
  @Input()
  iframeId!: string;

  constructor() {}

  ngOnInit(): void {
    console.log('iframeId', this.iframeId);
    let iframe = document.getElementById(this.iframeId) as HTMLIFrameElement;

    console.log('iframe', iframe);

    iframe?.addEventListener('load', () => {
      console.log('iframe loaded ?');
      let iframeWindow = iframe.contentWindow;
    });
  }
}

iframe.component.ts :

<iframe
  [id]="iframeId"
  srcdoc="
        <p>Some iframe content</p>
  "
></iframe>

And the result on the console :

iframeId iframe0 
iframe null 
iframeId iframe1 
iframe null 
iframeId iframe2 
iframe null 
Angular is running in development mode. Call enableProdMode() to enable production mode.
iframeId undefined
iframe null
Angular is running in development mode. Call enableProdMode() to enable production mode.

Note : I don't know why the three last lines are here, I hope it's just a stackblitz bug.

One last thing I noted is when I inspected the DOM, the first iframe has an undefined id while the second and third have iframe1 and iframe2 respectively.

So, my question is : how can I get the reference of my iframe ? Is it possible with the id attribute if passing by the @Input() ? If not, how ? I thought about @ViewChild or @ViewChildren but I would prefer the "id" method.

Neyt
  • 479
  • 1
  • 12
  • 27

1 Answers1

1

Your content is undefined because it's not loaded yet. You can check Angular Lifecycle for this.

Instead of using your code in ngOnInit() try to check on ngAfterViewInit() who's called once after ngAfterContentChecked(). I've tried on your stackblitz code and it worked.

Something like (on your iframe.component.ts):

  ngOnInit() {}

  ngAfterViewInit(): void {
    console.log('iframeId', this.iframeId);
    let iframe = document.getElementById(this.iframeId) as HTMLIFrameElement;

    console.log('iframe', iframe);

    iframe?.addEventListener('load', () => {
      console.log('iframe loaded ?');
      let iframeWindow = iframe.contentWindow;
    });
  }
José Lourenço
  • 129
  • 3
  • 4