Skip to content

Commit 2360676

Browse files
Dzmitry Shylovichvicb
authored andcommitted
fix(router): shouldn't execute CanLoad when a route has been loaded
Closes #14475 Closes #15438
1 parent ce3e03f commit 2360676

File tree

2 files changed

+55
-8
lines changed

2 files changed

+55
-8
lines changed

packages/router/src/apply_redirects.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -293,16 +293,18 @@ class ApplyRedirects {
293293
}
294294

295295
if (route.loadChildren) {
296+
if ((<any>route)._loadedConfig !== void 0) {
297+
return of ((<any>route)._loadedConfig);
298+
}
299+
296300
return mergeMap.call(runCanLoadGuard(ngModule.injector, route), (shouldLoad: boolean) => {
297301

298302
if (shouldLoad) {
299-
return (<any>route)._loadedConfig ?
300-
of ((<any>route)._loadedConfig) :
301-
map.call(
302-
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
303-
(<any>route)._loadedConfig = cfg;
304-
return cfg;
305-
});
303+
return map.call(
304+
this.configLoader.load(ngModule.injector, route), (cfg: LoadedRouterConfig) => {
305+
(<any>route)._loadedConfig = cfg;
306+
return cfg;
307+
});
306308
}
307309

308310
return canLoadFails(route);

packages/router/test/integration.spec.ts

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2075,7 +2075,9 @@ describe('Integration', () => {
20752075
});
20762076

20772077
describe('CanLoad', () => {
2078+
let canLoadRunCount = 0;
20782079
beforeEach(() => {
2080+
canLoadRunCount = 0;
20792081
TestBed.configureTestingModule({
20802082
providers: [
20812083
{provide: 'alwaysFalse', useValue: (a: any) => false},
@@ -2087,7 +2089,13 @@ describe('Integration', () => {
20872089
},
20882090
deps: [Router],
20892091
},
2090-
{provide: 'alwaysTrue', useValue: (a: any) => true},
2092+
{
2093+
provide: 'alwaysTrue',
2094+
useValue: () => {
2095+
canLoadRunCount++;
2096+
return true;
2097+
}
2098+
},
20912099
]
20922100
});
20932101
});
@@ -2173,6 +2181,43 @@ describe('Integration', () => {
21732181
[NavigationStart, '/blank'], [RoutesRecognized, '/blank'], [NavigationEnd, '/blank']
21742182
]);
21752183
})));
2184+
2185+
it('should execute CanLoad only once',
2186+
fakeAsync(inject(
2187+
[Router, Location, NgModuleFactoryLoader],
2188+
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
2189+
2190+
@Component({selector: 'lazy', template: 'lazy-loaded'})
2191+
class LazyLoadedComponent {
2192+
}
2193+
2194+
@NgModule({
2195+
declarations: [LazyLoadedComponent],
2196+
imports:
2197+
[RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])]
2198+
})
2199+
class LazyLoadedModule {
2200+
}
2201+
2202+
loader.stubbedModules = {lazy: LazyLoadedModule};
2203+
const fixture = createRoot(router, RootCmp);
2204+
2205+
router.resetConfig([{path: 'lazy', canLoad: ['alwaysTrue'], loadChildren: 'lazy'}]);
2206+
2207+
router.navigateByUrl('/lazy/loaded');
2208+
advance(fixture);
2209+
expect(location.path()).toEqual('/lazy/loaded');
2210+
expect(canLoadRunCount).toEqual(1);
2211+
2212+
router.navigateByUrl('/');
2213+
advance(fixture);
2214+
expect(location.path()).toEqual('/');
2215+
2216+
router.navigateByUrl('/lazy/loaded');
2217+
advance(fixture);
2218+
expect(location.path()).toEqual('/lazy/loaded');
2219+
expect(canLoadRunCount).toEqual(1);
2220+
})));
21762221
});
21772222

21782223
describe('order', () => {

0 commit comments

Comments
 (0)