Skip to content

Commit

Permalink
fix(router): fix lazy loading triggered by redirects from wildcard ro…
Browse files Browse the repository at this point in the history
…utes

Closes angular#12183
  • Loading branch information
vsavkin committed Oct 12, 2016
1 parent af996ef commit 19c9071
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 5 deletions.
12 changes: 7 additions & 5 deletions modules/@angular/router/src/apply_redirects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,6 @@ class ApplyRedirects {
if (getOutlet(route) !== outlet) return noMatch(segmentGroup);
if (route.redirectTo !== undefined && !(allowRedirects && this.allowRedirects))
return noMatch(segmentGroup);

if (route.redirectTo === undefined) {
return this.matchSegmentAgainstRoute(injector, segmentGroup, route, paths);
} else {
Expand All @@ -172,20 +171,23 @@ class ApplyRedirects {
injector: Injector, segmentGroup: UrlSegmentGroup, routes: Route[], route: Route,
segments: UrlSegment[], outlet: string): Observable<UrlSegmentGroup> {
if (route.path === '**') {
return this.expandWildCardWithParamsAgainstRouteUsingRedirect(route);
return this.expandWildCardWithParamsAgainstRouteUsingRedirect(
injector, routes, route, outlet);
} else {
return this.expandRegularSegmentAgainstRouteUsingRedirect(
injector, segmentGroup, routes, route, segments, outlet);
}
}

private expandWildCardWithParamsAgainstRouteUsingRedirect(route: Route):
Observable<UrlSegmentGroup> {
private expandWildCardWithParamsAgainstRouteUsingRedirect(
injector: Injector, routes: Route[], route: Route,
outlet: string): Observable<UrlSegmentGroup> {
const newSegments = applyRedirectCommands([], route.redirectTo, {});
if (route.redirectTo.startsWith('/')) {
return absoluteRedirect(newSegments);
} else {
return of (new UrlSegmentGroup(newSegments, {}));
const group = new UrlSegmentGroup(newSegments, {});
return this.expandSegment(injector, group, routes, newSegments, outlet, false);
}
}

Expand Down
28 changes: 28 additions & 0 deletions modules/@angular/router/test/apply_redirects.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,34 @@ describe('applyRedirects', () => {
expect((<any>config[0])._loadedConfig).toBe(loadedConfig);
});
});

it('should load the configuration after a local redirect from a whilecard route', () => {
const loadedConfig = new LoadedRouterConfig(
[{path: '', component: ComponentB}], <any>'stubInjector', <any>'stubFactoryResolver');

const loader = {load: (injector: any, p: any) => of (loadedConfig)};

const config =
[{path: 'not-found', loadChildren: 'children'}, {path: '**', redirectTo: 'not-found'}];

applyRedirects(<any>'providedInjector', <any>loader, tree('xyz'), config).forEach(r => {
expect((<any>config[0])._loadedConfig).toBe(loadedConfig);
});
});

it('should load the configuration after an absolute redirect from a whilecard route', () => {
const loadedConfig = new LoadedRouterConfig(
[{path: '', component: ComponentB}], <any>'stubInjector', <any>'stubFactoryResolver');

const loader = {load: (injector: any, p: any) => of (loadedConfig)};

const config =
[{path: 'not-found', loadChildren: 'children'}, {path: '**', redirectTo: '/not-found'}];

applyRedirects(<any>'providedInjector', <any>loader, tree('xyz'), config).forEach(r => {
expect((<any>config[0])._loadedConfig).toBe(loadedConfig);
});
});
});

describe('empty paths', () => {
Expand Down
28 changes: 28 additions & 0 deletions modules/@angular/router/test/integration.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1561,6 +1561,7 @@ describe('Integration', () => {
.toEqual(
`RouterModule.forRoot() called twice. Lazy loaded modules should use RouterModule.forChild() instead.`);
})));

it('should combine routes from multiple modules into a single configuration',
fakeAsync(inject(
[Router, Location, NgModuleFactoryLoader],
Expand Down Expand Up @@ -1704,6 +1705,33 @@ describe('Integration', () => {
[[NavigationStart, '/lazy/loaded'], [NavigationError, '/lazy/loaded']]);
})));

it('should work with complex redirect rules',
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 LoadedModule {
}

loader.stubbedModules = {lazy: LoadedModule};
const fixture = createRoot(router, RootCmp);

router.resetConfig(
[{path: 'lazy', loadChildren: 'lazy'}, {path: '**', redirectTo: 'lazy'}]);

router.navigateByUrl('/lazy/loaded');
advance(fixture);

expect(location.path()).toEqual('/lazy/loaded');
})));

describe('preloading', () => {
beforeEach(() => {
TestBed.configureTestingModule(
Expand Down

0 comments on commit 19c9071

Please sign in to comment.