Skip to content

Commit

Permalink
fix(youtube-player): ready event not emitting
Browse files Browse the repository at this point in the history
Fixes that the `youtube-player`'s `ready` event wasn't emitting. The issue is that we create the outputs lazily based on a stream of newly-created players, however that stream emits after the `ready` event.

Relates to #29874.

(cherry picked from commit 96afa88)
  • Loading branch information
crisbeto committed Nov 11, 2024
1 parent 2885987 commit 09da06b
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 14 deletions.
5 changes: 0 additions & 5 deletions src/youtube-player/youtube-player.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -725,17 +725,12 @@ describe('YoutubePlayer', () => {

const player = noEventsApp.componentInstance.player;
const subscriptions: Subscription[] = [];
const readySpy = jasmine.createSpy('ready spy');
const stateChangeSpy = jasmine.createSpy('stateChange spy');
const playbackQualityChangeSpy = jasmine.createSpy('playbackQualityChange spy');
const playbackRateChangeSpy = jasmine.createSpy('playbackRateChange spy');
const errorSpy = jasmine.createSpy('error spy');
const apiChangeSpy = jasmine.createSpy('apiChange spy');

subscriptions.push(player.ready.subscribe(readySpy));
events.onReady({target: playerSpy});
expect(readySpy).toHaveBeenCalledWith({target: playerSpy});

subscriptions.push(player.stateChange.subscribe(stateChangeSpy));
events.onStateChange({target: playerSpy, data: 5});
expect(stateChangeSpy).toHaveBeenCalledWith({target: playerSpy, data: 5});
Expand Down
17 changes: 13 additions & 4 deletions src/youtube-player/youtube-player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
CSP_NONCE,
ChangeDetectorRef,
AfterViewInit,
EventEmitter,
} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
import {Observable, of as observableOf, Subject, BehaviorSubject, fromEventPattern} from 'rxjs';
Expand Down Expand Up @@ -218,22 +219,29 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
*/
@Input() placeholderImageQuality: PlaceholderImageQuality;

/** Outputs are direct proxies from the player itself. */
@Output() readonly ready: Observable<YT.PlayerEvent> =
this._getLazyEmitter<YT.PlayerEvent>('onReady');
// Note: ready event can't go through the lazy emitter, because it
// happens before the `_playerChanges` stream emits the new player.

/** Emits when the player is initialized. */
@Output() readonly ready: Observable<YT.PlayerEvent> = new EventEmitter<YT.PlayerEvent>();

/** Emits when the state of the player has changed. */
@Output() readonly stateChange: Observable<YT.OnStateChangeEvent> =
this._getLazyEmitter<YT.OnStateChangeEvent>('onStateChange');

/** Emits when there's an error while initializing the player. */
@Output() readonly error: Observable<YT.OnErrorEvent> =
this._getLazyEmitter<YT.OnErrorEvent>('onError');

/** Emits when the underlying API of the player has changed. */
@Output() readonly apiChange: Observable<YT.PlayerEvent> =
this._getLazyEmitter<YT.PlayerEvent>('onApiChange');

/** Emits when the playback quality has changed. */
@Output() readonly playbackQualityChange: Observable<YT.OnPlaybackQualityChangeEvent> =
this._getLazyEmitter<YT.OnPlaybackQualityChangeEvent>('onPlaybackQualityChange');

/** Emits when the playback rate has changed. */
@Output() readonly playbackRateChange: Observable<YT.OnPlaybackRateChangeEvent> =
this._getLazyEmitter<YT.OnPlaybackRateChangeEvent>('onPlaybackRateChange');

Expand Down Expand Up @@ -575,7 +583,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
}),
);

const whenReady = () => {
const whenReady = (event: YT.PlayerEvent) => {
// Only assign the player once it's ready, otherwise YouTube doesn't expose some APIs.
this._ngZone.run(() => {
this._isLoading = false;
Expand All @@ -584,6 +592,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
this._pendingPlayer = undefined;
player.removeEventListener('onReady', whenReady);
this._playerChanges.next(player);
(this.ready as EventEmitter<YT.PlayerEvent>).emit(event);
this._setSize();
this._setQuality();

Expand Down
5 changes: 0 additions & 5 deletions tools/public_api_guard/youtube-player/youtube-player.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,10 @@ export const YOUTUBE_PLAYER_CONFIG: InjectionToken<YouTubePlayerConfig>;
// @public
export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
constructor(...args: unknown[]);
// (undocumented)
readonly apiChange: Observable<YT.PlayerEvent>;
disableCookies: boolean;
disablePlaceholder: boolean;
endSeconds: number | undefined;
// (undocumented)
readonly error: Observable<YT.OnErrorEvent>;
getAvailablePlaybackRates(): number[];
getAvailableQualityLevels(): YT.SuggestedVideoQuality[];
Expand Down Expand Up @@ -77,9 +75,7 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
pauseVideo(): void;
placeholderButtonLabel: string;
placeholderImageQuality: PlaceholderImageQuality;
// (undocumented)
readonly playbackQualityChange: Observable<YT.OnPlaybackQualityChangeEvent>;
// (undocumented)
readonly playbackRateChange: Observable<YT.OnPlaybackRateChangeEvent>;
playerVars: YT.PlayerVars | undefined;
playVideo(): void;
Expand All @@ -90,7 +86,6 @@ export class YouTubePlayer implements AfterViewInit, OnChanges, OnDestroy {
protected _shouldShowPlaceholder(): boolean;
showBeforeIframeApiLoads: boolean;
startSeconds: number | undefined;
// (undocumented)
readonly stateChange: Observable<YT.OnStateChangeEvent>;
stopVideo(): void;
suggestedQuality: YT.SuggestedVideoQuality | undefined;
Expand Down

0 comments on commit 09da06b

Please sign in to comment.