Skip to content

Commit

Permalink
refactor: use lazy injection token for router listener (#913)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidlj95 authored Oct 9, 2024
1 parent 66d5729 commit a959b94
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down Expand Up @@ -125,7 +125,7 @@ function makeSut(
],
})

return TestBed.inject(ROUTER_LISTENER)
return TestBed.inject(routerListener())
}

function makeNavigationEvent(type: EventType): NavigationEvent {
Expand Down
70 changes: 35 additions & 35 deletions projects/ngx-meta/src/routing/src/listener/router-listener.ts
Original file line number Diff line number Diff line change
@@ -1,51 +1,51 @@
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<RouterListener>(
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',
'Ensure routing provider or module is only imported once',
].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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -24,6 +24,6 @@ export const provideNgxMetaRouting = (): EnvironmentProviders =>
{
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useFactory: () => inject(ROUTER_LISTENER).listen,
useFactory: () => inject(routerListener()).listen,
},
])

0 comments on commit a959b94

Please sign in to comment.