From a959b94d5a5d225c5317b9af33c43b4185d5ce94 Mon Sep 17 00:00:00 2001 From: David LJ Date: Thu, 10 Oct 2024 00:10:14 +0200 Subject: [PATCH] refactor: use lazy injection token for router listener (#913) --- .../src/listener/router-listener.spec.ts | 4 +- .../routing/src/listener/router-listener.ts | 70 +++++++++---------- .../src/providers/provide-ngx-meta-routing.ts | 4 +- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/projects/ngx-meta/src/routing/src/listener/router-listener.spec.ts b/projects/ngx-meta/src/routing/src/listener/router-listener.spec.ts index e035a123..c174dcef 100644 --- a/projects/ngx-meta/src/routing/src/listener/router-listener.spec.ts +++ b/projects/ngx-meta/src/routing/src/listener/router-listener.spec.ts @@ -5,7 +5,7 @@ import { EventType, Router, RouterEvent } from '@angular/router' import { EventEmitter } from '@angular/core' import { enableAutoSpy } from '@/ngx-meta/test/enable-auto-spy' import { NgxMetaService } from '@davidlj95/ngx-meta/core' -import { ROUTER_LISTENER, RouterListener } from './router-listener' +import { routerListener, RouterListener } from './router-listener' import { Observable } from 'rxjs' describe('Router listener', () => { @@ -125,7 +125,7 @@ function makeSut( ], }) - return TestBed.inject(ROUTER_LISTENER) + return TestBed.inject(routerListener()) } function makeNavigationEvent(type: EventType): NavigationEvent { diff --git a/projects/ngx-meta/src/routing/src/listener/router-listener.ts b/projects/ngx-meta/src/routing/src/listener/router-listener.ts index 1104f2ec..d7cd0c18 100644 --- a/projects/ngx-meta/src/routing/src/listener/router-listener.ts +++ b/projects/ngx-meta/src/routing/src/listener/router-listener.ts @@ -1,27 +1,29 @@ -import { inject, InjectionToken, OnDestroy } from '@angular/core' +import { inject, OnDestroy } from '@angular/core' import { NavigationEnd, Router } from '@angular/router' import { filter, Subscription } from 'rxjs' -import { _formatDevMessage, NgxMetaService } from '@davidlj95/ngx-meta/core' +import { + _formatDevMessage, + _makeInjectionToken, + NgxMetaService, +} from '@davidlj95/ngx-meta/core' import { MODULE_NAME } from '../module-name' // WTF is this? Why not just import `EventType`? Well, compatibility reasons 🙃 // See https://github.com/davidlj95/ngx/pull/246 for the details const NAVIGATION_END_EVENT_TYPE = new NavigationEnd(0, '', '').type -export const ROUTER_LISTENER = new InjectionToken( - ngDevMode ? 'NgxMeta Router listener' : 'NgxMetaRL', - { - factory: () => { - const router = inject(Router) - const ngxMetaService = inject(NgxMetaService) - let subscription: Subscription | undefined - return { - listen() { - ngDevMode && - subscription && - // https://github.com/istanbuljs/istanbuljs/issues/719 - // prettier-ignore - console.warn( +export const routerListener = () => + _makeInjectionToken(ngDevMode ? 'Router listener' : 'RL', () => { + const router = inject(Router) + const ngxMetaService = inject(NgxMetaService) + let subscription: Subscription | undefined + return { + listen() { + ngDevMode && + subscription && + // https://github.com/istanbuljs/istanbuljs/issues/719 + // prettier-ignore + console.warn( _formatDevMessage( [ 'prevented listening for route changes twice', @@ -29,23 +31,21 @@ export const ROUTER_LISTENER = new InjectionToken( ].join('\n'), { module: MODULE_NAME }, )) - /* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */ - if (subscription) { - return - } - subscription = router.events - .pipe(filter(({ type }) => type === NAVIGATION_END_EVENT_TYPE)) - .subscribe({ - next: () => ngxMetaService.set(), - }) - }, - // Can't use DestroyRef is introduced in Angular v16 - // https://github.com/angular/angular/pull/49158 - // It uses EnvironmentInjector's internal `onDestroy` under the hood - // Tried that too, but it's @internal + raises some errors. So back to the `ngOnDestroy` - ngOnDestroy: () => subscription?.unsubscribe(), - } - }, - }, -) + /* istanbul ignore next https://github.com/istanbuljs/istanbuljs/issues/719 */ + if (subscription) { + return + } + subscription = router.events + .pipe(filter(({ type }) => type === NAVIGATION_END_EVENT_TYPE)) + .subscribe({ + next: () => ngxMetaService.set(), + }) + }, + // Can't use DestroyRef is introduced in Angular v16 + // https://github.com/angular/angular/pull/49158 + // It uses EnvironmentInjector's internal `onDestroy` under the hood + // Tried that too, but it's @internal + raises some errors. So back to the `ngOnDestroy` + ngOnDestroy: () => subscription?.unsubscribe(), + } + }) export type RouterListener = { listen: () => void } & OnDestroy diff --git a/projects/ngx-meta/src/routing/src/providers/provide-ngx-meta-routing.ts b/projects/ngx-meta/src/routing/src/providers/provide-ngx-meta-routing.ts index 18a3618e..37287095 100644 --- a/projects/ngx-meta/src/routing/src/providers/provide-ngx-meta-routing.ts +++ b/projects/ngx-meta/src/routing/src/providers/provide-ngx-meta-routing.ts @@ -5,7 +5,7 @@ import { makeEnvironmentProviders, } from '@angular/core' import { DEFAULT_ROUTE_METADATA_STRATEGY_PROVIDER } from '../route-metadata/default-route-metadata-strategy' -import { ROUTER_LISTENER } from '../listener/router-listener' +import { routerListener } from '../listener/router-listener' /** * Allows to manage metadata of a page by specifying it in its Angular @@ -24,6 +24,6 @@ export const provideNgxMetaRouting = (): EnvironmentProviders => { provide: ENVIRONMENT_INITIALIZER, multi: true, - useFactory: () => inject(ROUTER_LISTENER).listen, + useFactory: () => inject(routerListener()).listen, }, ])