I am trying to interact with a Youtube Embed API via a YoutubeHandler I am making. Since the API is only an interface to the player in an iframe with processing/buffering between calls I need to listen to state change events to be sure. Everything works fine except I am not sure why the state listeners are not being removed, it seems that I am using the same reference when adding and removing the listener. The Promise resolves just fine but the listener stays attached. Is there anything else I am missing? I am sure I am probably not accounting for something regarding scope. What is the next best way to solve this? I need to be able to reach the resolve() reject() of the Promise. I would like to figure this out but before trying to use an AbortController to remove the listener. Using Typescript with ES6.
Within my YoutubeHandler class (in a ts file), my play() is very similar to this pause() so it has the same issue:
async pause(onTime?: Time): Promise<boolean> { console.log("YOUTUBE-handler: Pausing video", this.player); this.pauseIgnore ++; // Increase pause ignore return new Promise(((resolve,reject) => { // Event handler that awaits and resolves the pause promise when it occurs let pauseAwait = (event: any)=>{ // Remove this event handler from future events console.log("DELETED PAUSE AWAIT",this.player,pauseAwait); this.player.removeEventListener(YTEvent.STATE_CHANGE,pauseAwait); // Resolve or reject if(event.data != undefined){ if (event.data == YTPlayerState.PAUSED) { resolve(true); } else { // TODO timeout reject reject("Did not receive a pause state. Received: "+ event.data); } } else { throw new Error("onStateChange event did not provide a data") } } console.log("STARTED PAUSE AWAIT",this.player) this.player.addEventListener(YTEvent.STATE_CHANGE, pauseAwait); this.player.pauseVideo(); })); }The compiled ES6 JS code looks practically identical.
This is what my browser console log looks like after several play (event.data = 1) and pause (event.data = 1) events:
youtube-handler.ts:117 YOUTUBE-handler: Playing video An {i: nn, h: iframe#player, m: null, j: 2, u: true, …}youtube-handler.ts:150 STARTED PLAY AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …}youtube-handler.ts:101 YT Handler -1 {video_id: '<vid>', author: '', title: '<title>'}youtube-handler.ts:101 YT Handler 3 {video_id: '<vid>', author: '', title: '<title>'}youtube-handler.ts:101 YT Handler -1 {video_id: '<vid>', author: '<author>', title: '<title>', video_quality: 'hd720', video_quality_features: Array(0)}youtube-handler.ts:101 YT Handler 3 {video_id: '<vid>', author: '<author>', title: '<title>', video_quality: 'hd720', video_quality_features: Array(0)}youtube-handler.ts:101 YT Handler 1 {video_id: '<vid>', author: '<author>', title: '<title>', video_quality: 'hd720', video_quality_features: Array(0)}youtube-handler.ts:126 DELETED PLAY AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events const rmvListener = () => { console.log("DELETED PLAY AWAIT", this.play…<...>youtube-handler.ts:160 YOUTUBE-handler: Pausing video An {i: nn, h: iframe#player, m: null, j: 2, u: true, …}youtube-handler.ts:181 STARTED PAUSE AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …}youtube-handler.ts:101 YT Handler 2 {video_id: '<vid>', author: '<author>', title: '<title>', video_quality: 'hd720', video_quality_features: Array(0)}youtube-handler.ts:126 DELETED PLAY AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events const rmvListener = () => { console.log("DELETED PLAY AWAIT", this.play…youtube-handler.ts:168 DELETED PAUSE AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events console.log("DELETED PAUSE AWAIT", this.player, pauseAwait); this.player.re…<...>youtube-handler.ts:117 YOUTUBE-handler: Playing video An {i: nn, h: iframe#player, m: null, j: 2, u: true, …}youtube-handler.ts:150 STARTED PLAY AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …}youtube-handler.ts:101 YT Handler 1 {video_id: '<vid>', author: '<author>', title: '<title>', video_quality: 'hd720', video_quality_features: Array(0)}youtube-handler.ts:126 DELETED PLAY AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events const rmvListener = () => { console.log("DELETED PLAY AWAIT", this.play…youtube-handler.ts:168 DELETED PAUSE AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events console.log("DELETED PAUSE AWAIT", this.player, pauseAwait); this.player.re…youtube-handler.ts:126 DELETED PLAY AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events const rmvListener = () => { console.log("DELETED PLAY AWAIT", this.play…<...>youtube-handler.ts:160 YOUTUBE-handler: Pausing video An {i: nn, h: iframe#player, m: null, j: 2, u: true, …}youtube-handler.ts:181 STARTED PAUSE AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …}youtube-handler.ts:101 YT Handler 2 {video_id: '<vid>', author: '<author>', title: '<title>', video_quality: 'hd720', video_quality_features: Array(0)}youtube-handler.ts:126 DELETED PLAY AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events const rmvListener = () => { console.log("DELETED PLAY AWAIT", this.play…youtube-handler.ts:168 DELETED PAUSE AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events console.log("DELETED PAUSE AWAIT", this.player, pauseAwait); this.player.re…youtube-handler.ts:126 DELETED PLAY AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events const rmvListener = () => { console.log("DELETED PLAY AWAIT", this.play…youtube-handler.ts:168 DELETED PAUSE AWAIT An {i: nn, h: iframe#player, m: null, j: 2, u: true, …} (event) => { // Remove this event handler from future events console.log("DELETED PAUSE AWAIT", this.player, pauseAwait); this.player.re…You can see that the play listener stayed attached and the pause listener will stay attached aswell resulting in continuously stacking "DELETED PLAY AWAIT, DELETED PAUSE AWAIT, DELETED PLAY AWAIT..." messages with each play and pause.
Thanks!