fix(router): handle new navigations from a NavigationEnd event (#41262)

This commit removes the line to set `currentNavigation` to `null` in the
navigation transitions subscription of the router. This logic is
already handled in the `finalize` stage of the transition pipe and has
been found to cause issues if a new navigation is triggered from a
subscription to the `NavigationEnd` event.

fixes #37460

PR Close #41262
This commit is contained in:
Andrew Scott 2021-03-18 09:10:22 -07:00 committed by Zach Arend
parent deacc741e0
commit 44a7fae00f
2 changed files with 36 additions and 1 deletions

View File

@ -1293,7 +1293,6 @@ export class Router {
.next(new NavigationEnd(
t.id, this.serializeUrl(t.extractedUrl), this.serializeUrl(this.currentUrlTree)));
this.lastSuccessfulNavigation = this.currentNavigation;
this.currentNavigation = null;
t.resolve(true);
},
e => {

View File

@ -18,6 +18,10 @@ describe('bootstrap', () => {
let log: any[] = [];
let testProviders: any[] = null!;
@Component({template: 'simple'})
class SimpleCmp {
}
@Component({selector: 'test-app', template: 'root <router-outlet></router-outlet>'})
class RootCmp {
constructor() {
@ -394,4 +398,36 @@ describe('bootstrap', () => {
expect(window.removeEventListener).toHaveBeenCalledWith('popstate', jasmine.any(Function));
expect(window.removeEventListener).toHaveBeenCalledWith('hashchange', jasmine.any(Function));
});
it('can schedule a navigation from the NavigationEnd event #37460', async (done) => {
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot(
[
{path: 'a', component: SimpleCmp},
{path: 'b', component: SimpleCmp},
],
)
],
declarations: [RootCmp, SimpleCmp],
bootstrap: [RootCmp],
providers: [...testProviders],
})
class TestModule {
}
const res = await platformBrowserDynamic([]).bootstrapModule(TestModule);
const router = res.injector.get(Router);
router.events.subscribe(() => {
expect(router.getCurrentNavigation()?.id).toBeDefined();
});
router.events.subscribe(async (e) => {
if (e instanceof NavigationEnd && e.url === '/b') {
await router.navigate(['a']);
done();
}
});
await router.navigateByUrl('/b');
});
});