@@ -44,7 +44,6 @@ import {
4444 combineLatest as combineLatestOp ,
4545 distinctUntilChanged ,
4646 filter ,
47- first ,
4847 flatMap ,
4948 map ,
5049 publish ,
@@ -236,15 +235,24 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
236235 }
237236
238237 createEventsBoundInZone ( ) : YT . Events {
239- return {
240- onReady : this . _runInZone ( ( event ) => this . ready . emit ( event ) ) ,
241- onStateChange : this . _runInZone ( ( event ) => this . stateChange . emit ( event ) ) ,
242- onPlaybackQualityChange :
243- this . _runInZone ( ( event ) => this . playbackQualityChange . emit ( event ) ) ,
244- onPlaybackRateChange : this . _runInZone ( ( event ) => this . playbackRateChange . emit ( event ) ) ,
245- onError : this . _runInZone ( ( event ) => this . error . emit ( event ) ) ,
246- onApiChange : this . _runInZone ( ( event ) => this . apiChange . emit ( event ) ) ,
247- } ;
238+ const output : YT . Events = { } ;
239+ const events = new Map < keyof YT . Events , EventEmitter < any > > ( [
240+ [ 'onReady' , this . ready ] ,
241+ [ 'onStateChange' , this . stateChange ] ,
242+ [ 'onPlaybackQualityChange' , this . playbackQualityChange ] ,
243+ [ 'onPlaybackRateChange' , this . playbackRateChange ] ,
244+ [ 'onError' , this . error ] ,
245+ [ 'onApiChange' , this . apiChange ]
246+ ] ) ;
247+
248+ events . forEach ( ( emitter , name ) => {
249+ // Since these events all trigger change detection, only bind them if something is subscribed.
250+ if ( emitter . observers . length ) {
251+ output [ name ] = this . _runInZone ( event => emitter . emit ( event ) ) ;
252+ }
253+ } ) ;
254+
255+ return output ;
248256 }
249257
250258 ngAfterViewInit ( ) {
@@ -261,9 +269,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
261269
262270 private _runInZone < T extends ( ...args : any [ ] ) => void > ( callback : T ) :
263271 ( ...args : Parameters < T > ) => void {
264- return ( ...args : Parameters < T > ) => {
265- this . _ngZone . run ( ( ) => callback ( ...args ) ) ;
266- } ;
272+ return ( ...args : Parameters < T > ) => this . _ngZone . run ( ( ) => callback ( ...args ) ) ;
267273 }
268274
269275 /** Proxied methods. */
@@ -416,19 +422,18 @@ function bindSuggestedQualityToPlayer(
416422 * Returns an observable that emits the loaded player once it's ready. Certain properties/methods
417423 * won't be available until the iframe finishes loading.
418424 */
419- function waitUntilReady ( )
420- : OperatorFunction < UninitializedPlayer | undefined , Player | undefined > {
425+ function waitUntilReady ( ) : OperatorFunction < UninitializedPlayer | undefined , Player | undefined > {
421426 return flatMap ( player => {
422- if ( ! player ) {
423- return observableOf < Player | undefined > ( undefined ) ;
424- }
425- if ( 'getPlayerStatus' in player ) {
426- return observableOf ( player as Player ) ;
427- }
428- // The player is not initialized fully until the ready is called.
429- return fromPlayerOnReady ( player )
430- . pipe ( first ( ) , startWith ( undefined ) ) ;
431- } ) ;
427+ if ( ! player ) {
428+ return observableOf < Player | undefined > ( undefined ) ;
429+ }
430+ if ( 'getPlayerStatus' in player ) {
431+ return observableOf ( player as Player ) ;
432+ }
433+ // The player is not initialized fully until the ready is called.
434+ return fromPlayerOnReady ( player )
435+ . pipe ( take ( 1 ) , startWith ( undefined ) ) ;
436+ } ) ;
432437}
433438
434439/** Since removeEventListener is not on Player when it's initialized, we can't use fromEvent. */
0 commit comments