diff --git a/packages/core/src/hydration/event_replay.ts b/packages/core/src/hydration/event_replay.ts index 75d20460777..fb18b915e1a 100644 --- a/packages/core/src/hydration/event_replay.ts +++ b/packages/core/src/hydration/event_replay.ts @@ -98,8 +98,8 @@ export function withEventReplay(): Provider[] { { provide: ENVIRONMENT_INITIALIZER, useValue: () => { - const injector = inject(Injector); - const appRef = injector.get(ApplicationRef); + const appRef = inject(ApplicationRef); + const {injector} = appRef; // We have to check for the appRef here due to the possibility of multiple apps // being present on the same page. We only want to enable event replay for the // apps that actually want it. @@ -123,8 +123,8 @@ export function withEventReplay(): Provider[] { provide: APP_BOOTSTRAP_LISTENER, useFactory: () => { const appId = inject(APP_ID); - const injector = inject(Injector); const appRef = inject(ApplicationRef); + const {injector} = appRef; return () => { // We have to check for the appRef here due to the possibility of multiple apps @@ -155,6 +155,16 @@ export function withEventReplay(): Provider[] { // of the application is completed. This timing is similar to the unclaimed // dehydrated views cleanup timing. appRef.whenStable().then(() => { + // Note: we have to check whether the application is destroyed before + // performing other operations with the `injector`. + // The application may be destroyed **before** it becomes stable, so when + // the `whenStable` resolves, the injector might already be in + // a destroyed state. Thus, calling `injector.get` would throw an error + // indicating that the injector has already been destroyed. + if (appRef.destroyed) { + return; + } + const eventContractDetails = injector.get(JSACTION_EVENT_CONTRACT); initEventReplay(eventContractDetails, injector); const jsActionMap = injector.get(JSACTION_BLOCK_ELEMENT_MAP); diff --git a/packages/platform-server/test/event_replay_spec.ts b/packages/platform-server/test/event_replay_spec.ts index aec888abb82..5b951a53236 100644 --- a/packages/platform-server/test/event_replay_spec.ts +++ b/packages/platform-server/test/event_replay_spec.ts @@ -13,8 +13,11 @@ import { Directive, ErrorHandler, HostListener, + inject, + PendingTasks, PLATFORM_ID, } from '@angular/core'; +import {isPlatformBrowser} from '@angular/common'; import {withEventReplay} from '@angular/platform-browser'; import {EventPhase} from '@angular/core/primitives/event-dispatch'; @@ -363,6 +366,71 @@ describe('event replay', () => { expect(getAppContents(html)).toContain('