diff --git a/packages/service-worker/src/provider.ts b/packages/service-worker/src/provider.ts index b06011c85c8..0ef2453c646 100644 --- a/packages/service-worker/src/provider.ts +++ b/packages/service-worker/src/provider.ts @@ -40,6 +40,7 @@ export function ngswAppInitializer( } const ngZone = injector.get(NgZone); + const appRef = injector.get(ApplicationRef); // Set up the `controllerchange` event listener outside of // the Angular zone to avoid unnecessary change detections, @@ -48,10 +49,13 @@ export function ngswAppInitializer( // Wait for service worker controller changes, and fire an INITIALIZE action when a new SW // becomes active. This allows the SW to initialize itself even if there is no application // traffic. - navigator.serviceWorker.addEventListener('controllerchange', () => { - if (navigator.serviceWorker.controller !== null) { - navigator.serviceWorker.controller.postMessage({action: 'INITIALIZE'}); - } + const sw = navigator.serviceWorker; + const onControllerChange = () => sw.controller?.postMessage({action: 'INITIALIZE'}); + + sw.addEventListener('controllerchange', onControllerChange); + + appRef.onDestroy(() => { + sw.removeEventListener('controllerchange', onControllerChange); }); }); diff --git a/packages/service-worker/test/provider_spec.ts b/packages/service-worker/test/provider_spec.ts index f6d8f869a8c..0b4367b221e 100644 --- a/packages/service-worker/test/provider_spec.ts +++ b/packages/service-worker/test/provider_spec.ts @@ -168,7 +168,11 @@ const serviceWorkerModuleApi = 'ServiceWorkerModule'; provideServiceWorker('sw.js'), { provide: ApplicationRef, - useValue: {isStable: isStableSub.asObservable(), afterTick: new Subject()}, + useValue: { + isStable: isStableSub.asObservable(), + afterTick: new Subject(), + onDestroy: () => {}, + }, }, {provide: PLATFORM_ID, useValue: 'browser'}, { @@ -183,7 +187,11 @@ const serviceWorkerModuleApi = 'ServiceWorkerModule'; providers: [ { provide: ApplicationRef, - useValue: {isStable: isStableSub.asObservable(), afterTick: new Subject()}, + useValue: { + isStable: isStableSub.asObservable(), + afterTick: new Subject(), + onDestroy: () => {}, + }, }, {provide: PLATFORM_ID, useValue: 'browser'}, {