Skip to content

Commit e884c0c

Browse files
committedApr 1, 2019
fix(router): adjust setting navigationTransition when a new navigation cancels an existing one (#29636)
Prior to this change, if a navigation was ongoing and a new one came in, the router could get into a state where `router.currentNavigation` was `null` even though a navigation was executing. This change moves where we set the `currentNavigation` value so it's inside a `switchMap`. This solves the problem because the `finally` on the `switchMap` had been setting `currentNavigation` to `null` but the new `currentNavigation` value would have already been set. Essentially this was a timing problem and is resolved with this change. Fixes #29389 #29590 PR Close #29636
1 parent ab72e06 commit e884c0c

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed
 

‎packages/router/src/router.ts

+13-14
Original file line numberDiff line numberDiff line change
@@ -452,25 +452,24 @@ export class Router {
452452
...t, extractedUrl: this.urlHandlingStrategy.extract(t.rawUrl)
453453
} as NavigationTransition)),
454454

455-
// Store the Navigation object
456-
tap(t => {
457-
this.currentNavigation = {
458-
id: t.id,
459-
initialUrl: t.currentRawUrl,
460-
extractedUrl: t.extractedUrl,
461-
trigger: t.source,
462-
extras: t.extras,
463-
previousNavigation: this.lastSuccessfulNavigation ?
464-
{...this.lastSuccessfulNavigation, previousNavigation: null} :
465-
null
466-
};
467-
}),
468-
469455
// Using switchMap so we cancel executing navigations when a new one comes in
470456
switchMap(t => {
471457
let completed = false;
472458
let errored = false;
473459
return of (t).pipe(
460+
// Store the Navigation object
461+
tap(t => {
462+
this.currentNavigation = {
463+
id: t.id,
464+
initialUrl: t.currentRawUrl,
465+
extractedUrl: t.extractedUrl,
466+
trigger: t.source,
467+
extras: t.extras,
468+
previousNavigation: this.lastSuccessfulNavigation ?
469+
{...this.lastSuccessfulNavigation, previousNavigation: null} :
470+
null
471+
};
472+
}),
474473
switchMap(t => {
475474
const urlTransition =
476475
!this.navigated || t.extractedUrl.toString() !== this.browserUrlTree.toString();

‎packages/router/test/integration.spec.ts

+21
Original file line numberDiff line numberDiff line change
@@ -1071,6 +1071,27 @@ describe('Integration', () => {
10711071
]);
10721072
})));
10731073

1074+
it('should properly set currentNavigation when cancelling in-flight navigations',
1075+
fakeAsync(inject([Router], (router: Router) => {
1076+
const fixture = createRoot(router, RootCmp);
1077+
1078+
router.resetConfig([{path: 'user/:name', component: UserCmp}]);
1079+
1080+
router.navigateByUrl('/user/init');
1081+
advance(fixture);
1082+
1083+
router.navigateByUrl('/user/victor');
1084+
expect((router as any).currentNavigation).not.toBe(null);
1085+
router.navigateByUrl('/user/fedor');
1086+
// Due to https://github.com/angular/angular/issues/29389, this would be `false`
1087+
// when running a second navigation.
1088+
expect((router as any).currentNavigation).not.toBe(null);
1089+
advance(fixture);
1090+
1091+
expect((router as any).currentNavigation).toBe(null);
1092+
expect(fixture.nativeElement).toHaveText('user fedor');
1093+
})));
1094+
10741095
it('should handle failed navigations gracefully', fakeAsync(inject([Router], (router: Router) => {
10751096
const fixture = createRoot(router, RootCmp);
10761097

0 commit comments

Comments
 (0)
Please sign in to comment.