diff --git a/packages/router/src/router_config_loader.ts b/packages/router/src/router_config_loader.ts index 08d28c777a..f2f922b1e8 100644 --- a/packages/router/src/router_config_loader.ts +++ b/packages/router/src/router_config_loader.ts @@ -6,7 +6,7 @@ * found in the LICENSE file at https://angular.io/license */ -import {Compiler, InjectionToken, Injector, NgModuleFactory, NgModuleFactoryLoader, NgModuleRef} from '@angular/core'; +import {Compiler, InjectionToken, Injector, NgModuleFactory, NgModuleFactoryLoader, NgModuleRef, ɵstringify as stringify} from '@angular/core'; import {Observable} from 'rxjs/Observable'; import {fromPromise} from 'rxjs/observable/fromPromise'; import {of } from 'rxjs/observable/of'; @@ -41,7 +41,16 @@ export class RouterConfigLoader { const module = factory.create(parentInjector); - return new LoadedRouterConfig(flatten(module.injector.get(ROUTES)), module); + const parentRoutes = new Set(flatten(parentInjector.get(ROUTES))); + const moduleRoutes = + flatten(module.injector.get(ROUTES)).filter(route => !parentRoutes.has(route)); + + if (moduleRoutes.length === 0) { + throw new Error( + `A lazy loaded module must define at least 1 route, but it seems like the '${stringify(factory.moduleType)}' module hasn't defined any. Have you imported RouterModule.forChild(ROUTES) in this module?`); + } + + return new LoadedRouterConfig(moduleRoutes, module); }); } diff --git a/packages/router/test/integration.spec.ts b/packages/router/test/integration.spec.ts index 1168e14b7a..571406626f 100644 --- a/packages/router/test/integration.spec.ts +++ b/packages/router/test/integration.spec.ts @@ -2697,6 +2697,27 @@ describe('Integration', () => { expect(fixture.nativeElement).toHaveText('lazy-loaded-parent [lazy-loaded-child]'); }))); + it(`should throw an error when lazy loaded module does not provide any routes`, + fakeAsync(inject( + [Router, Location, NgModuleFactoryLoader], + (router: Router, location: Location, loader: SpyNgModuleFactoryLoader) => { + + @NgModule({}) + class LazyLoadedModule { + } + + loader.stubbedModules = {expected: LazyLoadedModule}; + + const fixture = createRoot(router, RootCmp); + + router.resetConfig([{path: 'lazy', loadChildren: 'expected'}]); + + router.navigateByUrl('/lazy'); + expect(() => advance(fixture)) + .toThrowError( + /A lazy loaded module must define at least 1 route, but it seems like the 'LazyLoadedModule' module hasn't defined any/); + }))); + it('should have 2 injector trees: module and element', fakeAsync(inject( [Router, Location, NgModuleFactoryLoader],