From 8785b2bf6db8c3ecc4bd5edcf667d5f2f53f5271 Mon Sep 17 00:00:00 2001 From: Dzmitry Shylovich Date: Fri, 24 Mar 2017 01:59:17 +0300 Subject: [PATCH] fix(router): shouldn't execute CanLoad when a route has been loaded Closes #14475 Closes #15438 --- packages/router/src/apply_redirects.ts | 16 ++++---- packages/router/test/integration.spec.ts | 47 +++++++++++++++++++++++- 2 files changed, 55 insertions(+), 8 deletions(-) diff --git a/packages/router/src/apply_redirects.ts b/packages/router/src/apply_redirects.ts index a1ee6792b6..0508cb7569 100644 --- a/packages/router/src/apply_redirects.ts +++ b/packages/router/src/apply_redirects.ts @@ -293,16 +293,18 @@ class ApplyRedirects { } if (route.loadChildren) { + if ((route)._loadedConfig !== void 0) { + return of ((route)._loadedConfig); + } + return mergeMap.call(runCanLoadGuard(ngModule.injector, route), (shouldLoad: boolean) => { if (shouldLoad) { - return (route)._loadedConfig ? - of ((route)._loadedConfig) : - map.call( - this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => { - (route)._loadedConfig = cfg; - return cfg; - }); + return map.call( + this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => { + (route)._loadedConfig = cfg; + return cfg; + }); } return canLoadFails(route); diff --git a/packages/router/test/integration.spec.ts b/packages/router/test/integration.spec.ts index d67c563b9c..50a5b97082 100644 --- a/packages/router/test/integration.spec.ts +++ b/packages/router/test/integration.spec.ts @@ -2075,7 +2075,9 @@ describe('Integration', () => { }); describe('CanLoad', () => { + let canLoadRunCount = 0; beforeEach(() => { + canLoadRunCount = 0; TestBed.configureTestingModule({ providers: [ {provide: 'alwaysFalse', useValue: (a: any) => false}, @@ -2087,7 +2089,13 @@ describe('Integration', () => { }, deps: [Router], }, - {provide: 'alwaysTrue', useValue: (a: any) => true}, + { + provide: 'alwaysTrue', + useValue: () => { + canLoadRunCount++; + return true; + } + }, ] }); }); @@ -2173,6 +2181,43 @@ describe('Integration', () => { [NavigationStart, '/blank'], [RoutesRecognized, '/blank'], [NavigationEnd, '/blank'] ]); }))); + + it('should execute CanLoad only once', + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + + @Component({selector: 'lazy', template: 'lazy-loaded'}) + class LazyLoadedComponent { + } + + @NgModule({ + declarations: [LazyLoadedComponent], + imports: + [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])] + }) + class LazyLoadedModule { + } + + loader.stubbedModules = {lazy: LazyLoadedModule}; + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{path: 'lazy', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}]); + + router.navigateByUrl('/lazy/loaded'); + advance(fixture); + expect(location.path()).toEqual('/lazy/loaded'); + expect(canLoadRunCount).toEqual(1); + + router.navigateByUrl('/'); + advance(fixture); + expect(location.path()).toEqual('/'); + + router.navigateByUrl('/lazy/loaded'); + advance(fixture); + expect(location.path()).toEqual('/lazy/loaded'); + expect(canLoadRunCount).toEqual(1); + }))); }); describe('order', () => {