Skip to content

Commit 5ae6915

Browse files
vsavkinalxhub
authored andcommitted
fix(router): fix lazy loading triggered by redirects from wildcard routes
Closes #12183
1 parent 8b9ab44 commit 5ae6915

File tree

3 files changed

+63
-5
lines changed

3 files changed

+63
-5
lines changed

modules/@angular/router/src/apply_redirects.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ class ApplyRedirects {
159159
if (getOutlet(route) !== outlet) return noMatch(segmentGroup);
160160
if (route.redirectTo !== undefined && !(allowRedirects && this.allowRedirects))
161161
return noMatch(segmentGroup);
162-
163162
if (route.redirectTo === undefined) {
164163
return this.matchSegmentAgainstRoute(injector, segmentGroup, route, paths);
165164
} else {
@@ -172,20 +171,23 @@ class ApplyRedirects {
172171
injector: Injector, segmentGroup: UrlSegmentGroup, routes: Route[], route: Route,
173172
segments: UrlSegment[], outlet: string): Observable<UrlSegmentGroup> {
174173
if (route.path === '**') {
175-
return this.expandWildCardWithParamsAgainstRouteUsingRedirect(route);
174+
return this.expandWildCardWithParamsAgainstRouteUsingRedirect(
175+
injector, routes, route, outlet);
176176
} else {
177177
return this.expandRegularSegmentAgainstRouteUsingRedirect(
178178
injector, segmentGroup, routes, route, segments, outlet);
179179
}
180180
}
181181

182-
private expandWildCardWithParamsAgainstRouteUsingRedirect(route: Route):
183-
Observable<UrlSegmentGroup> {
182+
private expandWildCardWithParamsAgainstRouteUsingRedirect(
183+
injector: Injector, routes: Route[], route: Route,
184+
outlet: string): Observable<UrlSegmentGroup> {
184185
const newSegments = applyRedirectCommands([], route.redirectTo, {});
185186
if (route.redirectTo.startsWith('/')) {
186187
return absoluteRedirect(newSegments);
187188
} else {
188-
return of (new UrlSegmentGroup(newSegments, {}));
189+
const group = new UrlSegmentGroup(newSegments, {});
190+
return this.expandSegment(injector, group, routes, newSegments, outlet, false);
189191
}
190192
}
191193

modules/@angular/router/test/apply_redirects.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,34 @@ describe('applyRedirects', () => {
305305
expect((<any>config[0])._loadedConfig).toBe(loadedConfig);
306306
});
307307
});
308+
309+
it('should load the configuration after a local redirect from a wildcard route', () => {
310+
const loadedConfig = new LoadedRouterConfig(
311+
[{path: '', component: ComponentB}], <any>'stubInjector', <any>'stubFactoryResolver');
312+
313+
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
314+
315+
const config =
316+
[{path: 'not-found', loadChildren: 'children'}, {path: '**', redirectTo: 'not-found'}];
317+
318+
applyRedirects(<any>'providedInjector', <any>loader, tree('xyz'), config).forEach(r => {
319+
expect((<any>config[0])._loadedConfig).toBe(loadedConfig);
320+
});
321+
});
322+
323+
it('should load the configuration after an absolute redirect from a wildcard route', () => {
324+
const loadedConfig = new LoadedRouterConfig(
325+
[{path: '', component: ComponentB}], <any>'stubInjector', <any>'stubFactoryResolver');
326+
327+
const loader = {load: (injector: any, p: any) => of (loadedConfig)};
328+
329+
const config =
330+
[{path: 'not-found', loadChildren: 'children'}, {path: '**', redirectTo: '/not-found'}];
331+
332+
applyRedirects(<any>'providedInjector', <any>loader, tree('xyz'), config).forEach(r => {
333+
expect((<any>config[0])._loadedConfig).toBe(loadedConfig);
334+
});
335+
});
308336
});
309337

310338
describe('empty paths', () => {

modules/@angular/router/test/integration.spec.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,6 +1562,7 @@ describe('Integration', () => {
15621562
.toEqual(
15631563
`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
15641564
})));
1565+
15651566
it('should combine routes from multiple modules into a single configuration',
15661567
fakeAsync(inject(
15671568
[Router, Location, NgModuleFactoryLoader],
@@ -1705,6 +1706,33 @@ describe('Integration', () => {
17051706
[[NavigationStart, '/lazy/loaded'], [NavigationError, '/lazy/loaded']]);
17061707
})));
17071708

1709+
it('should work with complex redirect rules',
1710+
fakeAsync(inject(
1711+
[Router, Location, NgModuleFactoryLoader],
1712+
(router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => {
1713+
@Component({selector: 'lazy', template: 'lazy-loaded'})
1714+
class LazyLoadedComponent {
1715+
}
1716+
1717+
@NgModule({
1718+
declarations: [LazyLoadedComponent],
1719+
imports: [RouterModule.forChild([{path: 'loaded', component: LazyLoadedComponent}])],
1720+
})
1721+
class LoadedModule {
1722+
}
1723+
1724+
loader.stubbedModules = {lazy: LoadedModule};
1725+
const fixture = createRoot(router, RootCmp);
1726+
1727+
router.resetConfig(
1728+
[{path: 'lazy', loadChildren: 'lazy'}, {path: '**', redirectTo: 'lazy'}]);
1729+
1730+
router.navigateByUrl('/lazy/loaded');
1731+
advance(fixture);
1732+
1733+
expect(location.path()).toEqual('/lazy/loaded');
1734+
})));
1735+
17081736
describe('preloading', () => {
17091737
beforeEach(() => {
17101738
TestBed.configureTestingModule(

0 commit comments

Comments
 (0)