Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Youtube Iframe can't work without refresh

To reproduce the problem in Stackblitz, click GO to navigate to the component containing iframe, it works now, then go back and forward, the iframe disappears. You have to refresh the page to show the iframe again.

I tried some workaround :

  • I tried to release the object in ngOnDestroy window['onYouTubeIframeAPIReady'] = null; but not success

This is the code how to create iframe

init() {
  var tag = document.createElement('script');
  tag.src = 'https://www.youtube.com/iframe_api';
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
}

ngOnInit() {
  this.init();
  window['onYouTubeIframeAPIReady'] = (e) => {
            this.YT = window['YT'];

            this.player = new window['YT'].Player('player', {
              videoId: '1cH2cerUpMQ'
            });
  };
}

TEMPLATE

 <div id="player" >
 </div>

Someone has a workaround with success please share, please.

like image 772
Antoine V Avatar asked Mar 18 '26 18:03

Antoine V


2 Answers

You can check if youtube api has been already initialized and then just create your player:

player: any;

init() {
  if (window['YT']) {
    this.createPlayer();
    return;
  }

  var tag = document.createElement('script');
  tag.src = 'https://www.youtube.com/iframe_api';
  var firstScriptTag = document.getElementsByTagName('script')[0];
  firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

  window['onYouTubeIframeAPIReady'] = () => this.createPlayer();
}

ngOnInit() {
  this.init();
}

createPlayer() {
  this.player = new window['YT'].Player('player', {
    videoId: '1cH2cerUpMQ'
  });
}

ngOnDestroy() {
  window['onYouTubeIframeAPIReady'] = null;
  if (this.player) {
    this.player.destroy();
  }
}

Forked Stackblitz

like image 84
yurzui Avatar answered Mar 21 '26 09:03

yurzui


After one week, a workaround that works but it seems "dirty".

In fact, after go back and forward, the function window['onYouTubeIframeAPIReady'] doesn't execute anymore.

So, I put a boolean in this method, reset to false if it's executed. Then, a function check to need to reload after a timeout 3s by considering this value

 //this.needToReload = true in constructor

 ngAfterViewInit(){
    let n = 3;
    var intervalId= setInterval(() => {
            n--;
            this.tick = n*10;
            if (n === 0) {
                clearInterval(intervalId);
                if(this.needToReload)
                {
                  location.reload();
                }
            }
        }, 1000);
  } 

ngOnInit() {
    this.init();
    window['onYouTubeIframeAPIReady'] = (e) => {
        this.YT = window['YT'];
        this.needToReload = false;

        this.player = new window['YT'].Player('player', {
          videoId: '1cH2cerUpMQ'
        });
    };
}
like image 28
Antoine V Avatar answered Mar 21 '26 11:03

Antoine V