From 42a14e0e27518ee762c1c72315baf0e72d7bc8e4 Mon Sep 17 00:00:00 2001 From: jaybell Date: Wed, 1 Nov 2023 13:33:59 -0700 Subject: [PATCH 1/4] fix(api-loader): wait until stable to not block hydration --- .../src/lib/services/api-loader.service.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/projects/ngx-stripe/src/lib/services/api-loader.service.ts b/projects/ngx-stripe/src/lib/services/api-loader.service.ts index 374033f..536c780 100644 --- a/projects/ngx-stripe/src/lib/services/api-loader.service.ts +++ b/projects/ngx-stripe/src/lib/services/api-loader.service.ts @@ -1,10 +1,11 @@ -import { Inject, Injectable, PLATFORM_ID } from '@angular/core'; +import { ApplicationRef, Inject, Injectable, PLATFORM_ID } from '@angular/core'; import { isPlatformServer } from '@angular/common'; -import { Observable, BehaviorSubject } from 'rxjs'; +import { Observable, BehaviorSubject, concatMap } from 'rxjs'; import { WindowRef } from './window-ref.service'; import { DocumentRef } from './document-ref.service'; +import { filter, first } from 'rxjs/operators'; export interface LazyStripeAPILoaderStatus { loaded: boolean; @@ -20,11 +21,19 @@ export class LazyStripeAPILoader { loading: false }); - constructor(@Inject(PLATFORM_ID) public platformId: any, public window: WindowRef, public document: DocumentRef) {} + constructor( + @Inject(PLATFORM_ID) public platformId: any, + public window: WindowRef, + public document: DocumentRef, + public applicationRef: ApplicationRef + ) {} public asStream(): Observable { - this.load(); - return this.status.asObservable(); + return this.applicationRef.isStable.pipe( + filter((stable) => stable), + first(), + concatMap(() => this.status) + ); } public isReady(): boolean { From 5f9087afe4216c0955df1a9fb1de6963519396db Mon Sep 17 00:00:00 2001 From: jaybell Date: Wed, 1 Nov 2023 13:41:20 -0700 Subject: [PATCH 2/4] fix(api-loader): add timeout to add script after 10 seconds --- .../src/lib/services/api-loader.service.ts | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/projects/ngx-stripe/src/lib/services/api-loader.service.ts b/projects/ngx-stripe/src/lib/services/api-loader.service.ts index 536c780..7ad1df7 100644 --- a/projects/ngx-stripe/src/lib/services/api-loader.service.ts +++ b/projects/ngx-stripe/src/lib/services/api-loader.service.ts @@ -1,7 +1,7 @@ -import { ApplicationRef, Inject, Injectable, PLATFORM_ID } from '@angular/core'; +import { ApplicationRef, Inject, Injectable, isDevMode, PLATFORM_ID } from '@angular/core'; import { isPlatformServer } from '@angular/common'; -import { Observable, BehaviorSubject, concatMap } from 'rxjs'; +import { Observable, BehaviorSubject, concatMap, timeout, catchError, EMPTY } from 'rxjs'; import { WindowRef } from './window-ref.service'; import { DocumentRef } from './document-ref.service'; @@ -31,6 +31,14 @@ export class LazyStripeAPILoader { public asStream(): Observable { return this.applicationRef.isStable.pipe( filter((stable) => stable), + timeout(10_000), + catchError(() => { + if (isDevMode()) { + console.warn(`Application failed to become stable within 10000ms. Loading the Stripe script now.`) + } + + return EMPTY; + }), first(), concatMap(() => this.status) ); From a2b45f73b7edefa99efdccddc205710c14b647b4 Mon Sep 17 00:00:00 2001 From: jaybell Date: Thu, 2 Nov 2023 11:02:51 -0700 Subject: [PATCH 3/4] fix(api-loader): switch how streams are returned and call load --- .../ngx-stripe/src/lib/services/api-loader.service.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/projects/ngx-stripe/src/lib/services/api-loader.service.ts b/projects/ngx-stripe/src/lib/services/api-loader.service.ts index 7ad1df7..5ef4df6 100644 --- a/projects/ngx-stripe/src/lib/services/api-loader.service.ts +++ b/projects/ngx-stripe/src/lib/services/api-loader.service.ts @@ -29,7 +29,8 @@ export class LazyStripeAPILoader { ) {} public asStream(): Observable { - return this.applicationRef.isStable.pipe( + // Once the app is stable or stability has timed out then load the script. + this.applicationRef.isStable.pipe( filter((stable) => stable), timeout(10_000), catchError(() => { @@ -39,9 +40,10 @@ export class LazyStripeAPILoader { return EMPTY; }), - first(), - concatMap(() => this.status) - ); + first() + ).subscribe(() => this.load()) + + return this.status.asObservable(); } public isReady(): boolean { From 702cffbb5c606454884c8fa336fc7e20bd88ae74 Mon Sep 17 00:00:00 2001 From: jaybell Date: Thu, 2 Nov 2023 11:06:53 -0700 Subject: [PATCH 4/4] fix(api-loader): share the subscription for resubscription --- .../src/lib/services/api-loader.service.ts | 30 ++++++++++--------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/projects/ngx-stripe/src/lib/services/api-loader.service.ts b/projects/ngx-stripe/src/lib/services/api-loader.service.ts index 5ef4df6..bdae2e7 100644 --- a/projects/ngx-stripe/src/lib/services/api-loader.service.ts +++ b/projects/ngx-stripe/src/lib/services/api-loader.service.ts @@ -1,7 +1,7 @@ import { ApplicationRef, Inject, Injectable, isDevMode, PLATFORM_ID } from '@angular/core'; import { isPlatformServer } from '@angular/common'; -import { Observable, BehaviorSubject, concatMap, timeout, catchError, EMPTY } from 'rxjs'; +import { Observable, BehaviorSubject, concatMap, timeout, catchError, EMPTY, shareReplay } from 'rxjs'; import { WindowRef } from './window-ref.service'; import { DocumentRef } from './document-ref.service'; @@ -21,6 +21,20 @@ export class LazyStripeAPILoader { loading: false }); + private readonly isStable$ = this.applicationRef.isStable.pipe( + filter((stable) => stable), + timeout(10_000), + catchError(() => { + if (isDevMode()) { + console.warn(`Application failed to become stable within 10000ms. Loading the Stripe script now.`) + } + + return EMPTY; + }), + first(), + shareReplay(1) + ) + constructor( @Inject(PLATFORM_ID) public platformId: any, public window: WindowRef, @@ -29,19 +43,7 @@ export class LazyStripeAPILoader { ) {} public asStream(): Observable { - // Once the app is stable or stability has timed out then load the script. - this.applicationRef.isStable.pipe( - filter((stable) => stable), - timeout(10_000), - catchError(() => { - if (isDevMode()) { - console.warn(`Application failed to become stable within 10000ms. Loading the Stripe script now.`) - } - - return EMPTY; - }), - first() - ).subscribe(() => this.load()) + this.isStable$.subscribe(() => this.load()) return this.status.asObservable(); }