diff --git a/packages/router/src/router.ts b/packages/router/src/router.ts index db8c189ed4..fdf385220e 100644 --- a/packages/router/src/router.ts +++ b/packages/router/src/router.ts @@ -452,25 +452,24 @@ export class Router { ...t, extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl) } as NavigationTransition)), - // Store the Navigation object - tap(t => { - this.currentNavigation = { - id: t.id, - initialUrl: t.currentRawUrl, - extractedUrl: t.extractedUrl, - trigger: t.source, - extras: t.extras, - previousNavigation: this.lastSuccessfulNavigation ? - {...this.lastSuccessfulNavigation, previousNavigation: null} : - null - }; - }), - // Using switchMap so we cancel executing navigations when a new one comes in switchMap(t => { let completed = false; let errored = false; return of (t).pipe( + // Store the Navigation object + tap(t => { + this.currentNavigation = { + id: t.id, + initialUrl: t.currentRawUrl, + extractedUrl: t.extractedUrl, + trigger: t.source, + extras: t.extras, + previousNavigation: this.lastSuccessfulNavigation ? + {...this.lastSuccessfulNavigation, previousNavigation: null} : + null + }; + }), switchMap(t => { const urlTransition = !this.navigated || t.extractedUrl.toString() !== this.browserUrlTree.toString(); diff --git a/packages/router/test/integration.spec.ts b/packages/router/test/integration.spec.ts index 7b7d9fc022..e95386f18c 100644 --- a/packages/router/test/integration.spec.ts +++ b/packages/router/test/integration.spec.ts @@ -1067,6 +1067,27 @@ describe('Integration', () => { ]); }))); + it('should properly set currentNavigation when cancelling in-flight navigations', + fakeAsync(inject([Router], (router: Router) => { + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{path: 'user/:name', component: UserCmp}]); + + router.navigateByUrl('/user/init'); + advance(fixture); + + router.navigateByUrl('/user/victor'); + expect((router as any).currentNavigation).not.toBe(null); + router.navigateByUrl('/user/fedor'); + // Due to https://github.com/angular/angular/issues/29389, this would be `false` + // when running a second navigation. + expect((router as any).currentNavigation).not.toBe(null); + advance(fixture); + + expect((router as any).currentNavigation).toBe(null); + expect(fixture.nativeElement).toHaveText('user fedor'); + }))); + it('should handle failed navigations gracefully', fakeAsync(inject([Router], (router: Router) => { const fixture = createRoot(router, RootCmp);