Skip to content

refactor: handle stubbed window in SSR checks #17755

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/google-maps/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ng_module(
),
module_name = "@angular/google-maps",
deps = [
"@npm//@angular/common",
"@npm//@angular/core",
"@npm//@types/googlemaps",
"@npm//rxjs",
Expand Down
29 changes: 20 additions & 9 deletions src/google-maps/google-map/google-map.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ import {
OnInit,
Output,
ViewEncapsulation,
Optional,
Inject,
PLATFORM_ID,
} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';
import {BehaviorSubject, combineLatest, Observable, Subject} from 'rxjs';
import {map, shareReplay, take, takeUntil} from 'rxjs/operators';

Expand Down Expand Up @@ -48,12 +52,6 @@ export const DEFAULT_HEIGHT = '500px';
/** Arbitrary default width for the map element */
export const DEFAULT_WIDTH = '500px';

/**
* Whether we're currently rendering inside a browser. Equivalent of `Platform.isBrowser`,
* but copied over here so we don't have to add another dependency.
*/
const isBrowser = typeof window === 'object' && !!window;

/**
* Angular component that renders a Google Map via the Google Maps JavaScript
* API.
Expand Down Expand Up @@ -194,6 +192,8 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {
private _mapEl: HTMLElement;
_googleMap!: UpdatedGoogleMap;

/** Whether we're currently rendering inside a browser. */
private _isBrowser: boolean;
private _googleMapChanges!: Observable<google.maps.Map>;

private readonly _listeners: google.maps.MapsEventListener[] = [];
Expand All @@ -205,8 +205,19 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {

private readonly _destroy = new Subject<void>();

constructor(private readonly _elementRef: ElementRef) {
if (isBrowser) {
constructor(
private readonly _elementRef: ElementRef,
/**
* @deprecated `platformId` parameter to become required.
* @breaking-change 10.0.0
*/
@Optional() @Inject(PLATFORM_ID) platformId?: Object) {

// @breaking-change 10.0.0 Remove null check for `platformId`.
this._isBrowser =
platformId ? isPlatformBrowser(platformId) : typeof window === 'object' && !!window;

if (this._isBrowser) {
const googleMapsWindow: GoogleMapsWindow = window;
if (!googleMapsWindow.google) {
throw Error(
Expand All @@ -224,7 +235,7 @@ export class GoogleMap implements OnChanges, OnInit, OnDestroy {

ngOnInit() {
// It should be a noop during server-side rendering.
if (isBrowser) {
if (this._isBrowser) {
this._mapEl = this._elementRef.nativeElement.querySelector('.map-container')!;
this._setSize();

Expand Down
1 change: 1 addition & 0 deletions src/youtube-player/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ ng_module(
),
module_name = "@angular/youtube-player",
deps = [
"@npm//@angular/common",
"@npm//@angular/core",
"@npm//@types/youtube",
"@npm//rxjs",
Expand Down
29 changes: 20 additions & 9 deletions src/youtube-player/youtube-player.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ import {
Output,
ViewChild,
ViewEncapsulation,
Optional,
Inject,
PLATFORM_ID,
} from '@angular/core';
import {isPlatformBrowser} from '@angular/common';

import {
combineLatest,
Expand Down Expand Up @@ -72,12 +76,6 @@ interface Player extends YT.Player {
// The only field available is destroy and addEventListener.
type UninitializedPlayer = Pick<Player, 'videoId' | 'destroy' | 'addEventListener'>;

/**
* Whether we're currently rendering inside a browser. Equivalent of `Platform.isBrowser`,
* but copied over here so we don't have to add another dependency.
*/
const isBrowser = typeof window === 'object' && !!window;

/**
* Angular component that renders a YouTube player via the YouTube player
* iframe API.
Expand Down Expand Up @@ -158,15 +156,28 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
@ViewChild('youtubeContainer')
youtubeContainer: ElementRef<HTMLElement>;

/** Whether we're currently rendering inside a browser. */
private _isBrowser: boolean;
private _youtubeContainer = new EventEmitter<HTMLElement>();
private _destroyed = new EventEmitter<undefined>();
private _player: Player | undefined;

constructor(private _ngZone: NgZone) {}
constructor(
private _ngZone: NgZone,
/**
* @deprecated `platformId` parameter to become required.
* @breaking-change 10.0.0
*/
@Optional() @Inject(PLATFORM_ID) platformId?: Object) {

// @breaking-change 10.0.0 Remove null check for `platformId`.
this._isBrowser =
platformId ? isPlatformBrowser(platformId) : typeof window === 'object' && !!window;
}

ngOnInit() {
// Don't do anything if we're not in a browser environment.
if (!isBrowser) {
if (!this._isBrowser) {
return;
}

Expand Down Expand Up @@ -340,7 +351,7 @@ export class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {

/** See https://developers.google.com/youtube/iframe_api_reference#getPlayerState */
getPlayerState(): YT.PlayerState | undefined {
if (!isBrowser || !window.YT) {
if (!this._isBrowser || !window.YT) {
return undefined;
}

Expand Down
3 changes: 2 additions & 1 deletion tools/public_api_guard/google-maps/google-maps.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export declare class GoogleMap implements OnChanges, OnInit, OnDestroy {
width: string;
zoom: number;
zoomChanged: EventEmitter<void>;
constructor(_elementRef: ElementRef);
constructor(_elementRef: ElementRef,
platformId?: Object);
fitBounds(bounds: google.maps.LatLngBounds | google.maps.LatLngBoundsLiteral, padding?: number | google.maps.Padding): void;
getBounds(): google.maps.LatLngBounds | null;
getCenter(): google.maps.LatLng;
Expand Down
3 changes: 2 additions & 1 deletion tools/public_api_guard/youtube-player/youtube-player.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ export declare class YouTubePlayer implements AfterViewInit, OnDestroy, OnInit {
videoId: string | undefined;
width: number | undefined;
youtubeContainer: ElementRef<HTMLElement>;
constructor(_ngZone: NgZone);
constructor(_ngZone: NgZone,
platformId?: Object);
createEventsBoundInZone(): YT.Events;
getAvailablePlaybackRates(): number[];
getAvailableQualityLevels(): YT.SuggestedVideoQuality[];
Expand Down