Please provide us with the following information:
Windows 10
@angular/cli: 1.0.0-beta.30
node: 6.9.1
os: win32 x64
@angular/common: 2.4.7
@angular/compiler: 2.4.7
@angular/core: 2.4.7
@angular/forms: 2.4.7
@angular/http: 2.4.7
@angular/platform-browser: 2.4.7
@angular/platform-browser-dynamic: 2.4.7
@angular/router: 3.4.7
@angular/cli: 1.0.0-beta.30
@angular/compiler-cli: 2.4.7
feature.module.ts
Using @nglibs/i18n-router to provide route translations for feature modules (lazy loaded).
import { I18NRouterModule } from '@nglibs/i18n-router';
@NgModule({
imports: [
CommonModule,
// RouterModule.forChild(routes)
I18NRouterModule.forChild(routes, 'about')
],
declarations: [
AboutComponent,
AboutUsComponent,
AboutBananaComponent,
AboutApplePearComponent
]
})
The whole solution is located on github: angular-cli branch of @nglibs/example-app.
Can't talk about a stack trace, but hope it will be helpful:
$ ng serve
** NG Live Development Server is running on http://localhost:4200. **
Hash: ddefd75abb9ca8b82bd4 Time: 18958ms
chunk {0} polyfills.bundle.js, polyfills.bundle.map (polyfills) 222 kB {4} [initial] [rendered]
chunk {1} main.bundle.js, main.bundle.map (main) 8.61 kB {3} [initial] [rendered]
chunk {2} styles.bundle.js, styles.bundle.map (styles) 10 kB {4} [initial] [rendered]
chunk {3} vendor.bundle.js, vendor.bundle.map (vendor) 3.49 MB [initial] [rendered]
chunk {4} inline.bundle.js, inline.bundle.map (inline) 0 bytes [entry] [rendered]
ERROR in Cannot read property 'loadChildren' of undefined
webpack: Failed to compile.
@nglibs/i18n-router
does not work with @angular-cli
(yet), and giving the following error during [AoT compilation]:
ERROR in Cannot read property 'loadChildren' of undefined
I suppose @angular-cli
uses @ngtools/webpack
for [AoT compilation], expecting RouterModule.forChild(...)
to resolve lazy-loaded modules (with loadChildren
), which is replaced by I18NRouterModule.forChild(...)
- providing routes for feature modules instead.
Here's the piece of code from i18n-router module line 72, which provides child routes.
{
provide: ROUTES,
useFactory: (provideChildRoutes),
deps: [I18NRouterService, RAW_ROUTES, MODULE_KEY],
multi: true
},
{
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
useValue: routes,
multi: true
}
It provides ROUTES
and ANALYZE_FOR_ENTRY_COMPONENTS
to Angular the same way that the router module does (see below):
However, angular-cli seems insisting ignoring the provided child routes and firing errors.
To resolve this issue temporarily, I switched using [ng-router-loader]. Hence @angular-cli
doesn't allow modifying the webpack configuration, I need to manually configure build tools (dev/prod sever, task runners, webpack, etc).
I think loadChildren
should be able to recognize routes provided with ROUTES
and ANALYZE_FOR_ENTRY_COMPONENTS
.
That's where the lazy route discovery is happening:
I wasn't even aware there're other alternatives to this, but to start with, it seems to be considering the ROUTES
bit:
// We cannot depend directly to @angular/router.
type Route = any;
const ROUTER_MODULE_PATH = '@angular/router/src/router_config_loader';
const ROUTER_ROUTES_SYMBOL_NAME = 'ROUTES';
...
const ROUTES = reflector.findDeclaration(ROUTER_MODULE_PATH, ROUTER_ROUTES_SYMBOL_NAME);
No idea about ANALYZE_FOR_ENTRY_COMPONENTS
(maybe the core team of the CLI has better idea).
I wouldn't expect focus on this one from the core team before v1.0 final (could be wrong). Would you have any idea extending the above file to cater for your case?
I think this is essentially the same issue as https://github.com/angular/angular-cli/issues/4541, please have a look.
Hi @filipesilva, I've read #4541 and @christopherthielen talks about more or less a similar functionality.
Currently waiting for updates, and many thanks for your attention 馃憤
First of all I'd like to say thanks to @christopherthielen, for all the details he provided on #4541. This information was very helpful while analyzing the issue with @nglibs/i18n-router
.
As far as I can progress, I've found out that if I provide child routes unprocessed, then the @ngtools/webpack
can find the lazy routes.
{
provide: ROUTES,
useValue: routes,
// useFactory: (provideChildRoutes),
// deps: [I18NRouterService, RAW_ROUTES, MODULE_KEY],
multi: true
},
{
provide: ANALYZE_FOR_ENTRY_COMPONENTS,
useValue: routes,
multi: true
}
Now, the challenge is to get the @ngtools/webpack
identify routes provided by useFactory
.
I had the error. Found the cause in my case, want to share
in the TS app-routes module (of angular 5 project) I made a syntax error :
const routes: Routes = [
{ path: '', redirectTo:'/', pathMatch: 'full' }
, { path: 'a', component : aComponent }
, { path: 'a/detail/:id', component: aDetailComponent },
, { path: 'b', component : bComponent }
, { path: 'b/detail/:id', component : bDetailComponent }
];
The error is the
,
at the end of the 4th line, which delivers an empty element in the Routes array, which delivers the loadChildren error.
I had the same error as well, but the problem was I had move the app-router.module.ts outside app folder.
I had the same error but yet another cause. I was dynamically assigning a key to the routes
object:
const routes: Routes = [{
path: '',
component: SomeComponent,
children: [{
path: 'blah',
component: BlahCreateComponent,
resolve: {
[SOME_CONSTANT]: SomeResolver, // <-- you can't do this
},
}],
}]
I was only able to track down the issue by doing ng build --prod --aot
which gave me an more descriptive error.
@tomsaleeba and how you fixed it? you just deleted the resolve part?
@tomsaleeba
thank you for this clue.
i did similar thing: i set a constant as key
{
path: 'feature',
loadChildren: '...path-to-module...',
data: {
'menu-bar': MenuBar.Show,
[AFTER_LOGIN_PRELOADING_STRATEGY]: true
}
}
it's properly to set a key as direct definition or instant string value like data: { YEAR: 2018, 'month-text': 'August' }
@thiagofrancisquete as @korenb mentioned, it seems like you can't dynamically set the key of the object (using that syntax with the square braces [SOME_KEY]
. Instead, you need to directly define the key.
As a concrete example, assume I was trying to assing the dynamic key like this
const SOME_CONSTANT = 'theKey'
...
resolve: {
[SOME_CONSTANT]: SomeResolver,
},
...
...to fix it, you need to do this:
...
resolve: {
theKey: SomeResolver,
},
...
I had faced same issue. In My case I had not included my Route resolver in provider property of NgModule.
After declaring in provider this issue get fixed.
as I commented @bevlison I also had syntax error [ , , ]
export const AuthRoutes: Routes = [
{
path: '',
redirectTo: 'signin',
pathMatch: 'full'
}, {
path: 'signin',
component: SigninComponent
}, {
path: 'signup',
component: SignupComponent
}, {
path: 'reset-password',
component: ResetPasswordComponent
}, {
path: 'recover-email',
component: RecoverEmailComponent
},
, {
path: 'verify-email',
component: VerifyEmailComponent
}];
One final gotcha to contribute:
import { urls } from 'consts'
const { topLevelRoutes } = urls
const routes = [
{ path: topLevelRoutes.login, loadChildren: 'path/login.module#LoginModule' },
{ path: topLevelRoutes.dashboard, loadChildren: 'path/dashboard.module#DashboardModule' },
{ path: '**', redirectTo: topLevelRoutes.dashboard }
]
Fails with the aforementioned error.
import { urls } from 'consts'
// const { topLevelRoutes } = urls
const routes = [
{ path: urls.topLevelRoutes.login, loadChildren: 'path/login.module#LoginModule' },
{ path: urls.topLevelRoutes.dashboard, loadChildren: 'path/dashboard.module#DashboardModule' },
{ path: '**', redirectTo: urls.topLevelRoutes.dashboard }
]
Works fine.
Not sure if it's only a dev server thing and works with a proper build or not. Also not sure about any permutations. Obviously not a pain point, just wanted to add this in case somehow runs into a similar circumstance.
I came to this issue with a similar problem and actually found my fix here.
The problem I was having was I did not have the export
on my function as soon as I added export
to it I could build again. Sorry if this isn't specifically related to the OP but thought it may help someone.
I had the same error but yet another cause. I was dynamically assigning a key to the
routes
object:const routes: Routes = [{ path: '', component: SomeComponent, children: [{ path: 'blah', component: BlahCreateComponent, resolve: { [SOME_CONSTANT]: SomeResolver, // <-- you can't do this }, }], }]
I was only able to track down the issue by doing
ng build --prod --aot
which gave me an more descriptive error.
Sure, in my case this did the trick:
const routes: Routes = [];
routes.push(...links.map(link => <Route> { path: link.url, component: link.component }));
run angular using aot
option to get a full descriptive error
ng s --aot
I faced this error as well but for another reason.
I was passing a regex as value inside the data
:
data: { regex: /^([0-9]+)$/ }
I had to convert it to a string:
data: { regex: '^([0-9]+)$' }
I know this thread is becoming like stack overflow, but it's the first hit on Google. Here was my scenario.
Cause: routes was not defined as a constant.
I had a route configuration like:
let routes: Routes;
routes = [
{
path: '',
children: [
{
path: '',
children: [
{
path: '',
children: [
{path: '', component: HeaderComponent, outlet: 'header'},
{path: '', component: FooterComponent, outlet: 'footer'}
// Routes that display a header and footer go here.
]
},
{
path: '',
children: [
{
path: '/frame',
children: [{
path: 'search',
loadChildren: () => import('./search/search.module').then(module => module.SearchModule)
}]
}
]
}
]
}
]
}
];
Very specifically, while I was in ng serve
(npm start
) mode and the browser was at the /frame/search path, I modified the routes to include a ** path (just randomly adding stuff from another working application).
let routes: Routes;
routes = [
{
path: '',
children: [
{
path: '',
children: [
{
path: '',
children: [
{path: '', component: HeaderComponent, outlet: 'header'},
{path: '', component: FooterComponent, outlet: 'footer'}
// Routes that display a header and footer go here.
]
},
{
path: '',
children: [
{
path: '/frame',
children: [{
path: 'search',
loadChildren: () => import('./search/search.module').then(module => module.SearchModule)
}]
}
]
}
]
}
]
},
{
path: '**',
redirectTo: '/frame/search',
pathMatch: 'full'
}
];
The browser refreshed and there was a console error:
Uncaught Error: Component HeaderComponent is not part of any NgModule or the module has not been imported into your module.
So sure enough, I had not added those imports to the app.module. I don't know if the error message presented simply by making any change or by adding this specific route change. I do know that if I ran npm start
after adding the ** path, I could not get the console error to present.
After adding those imports I got another console error:
Invalid configuration of route '/frame': path cannot start with a slash
I fixed that:
let routes: Routes
routes = [
{
path: '',
children: [
{
path: '',
children: [
{
path: '',
children: [
{path: '', component: HeaderComponent, outlet: 'header'},
{path: '', component: FooterComponent, outlet: 'footer'}
// Routes that display a header and footer go here.
]
},
{
path: '',
data: {header: false, footer: false},
children: [
{
path: 'frame',
children: [{
path: 'search',
loadChildren: () => import('./search/search.module').then(module => module.SearchModule)
}]
}
]
}
]
}
]
},
{
path: '**',
redirectTo: '/frame/search',
pathMatch: 'full'
}
];
And I was good to go (or so I thought).
npm start
was still throwing the error.
Comparing the route files between a new project and mine, I noticed that routes was defined as a constant. I probably had copied in the routes from a prior project, or WebStorm modified the code somehow, not sure.
So finally my working app-routes.
const routes: Routes = [
{
path: '',
children: [
{
path: '',
children: [
{
path: '',
children: [
{path: '', component: HeaderComponent, outlet: 'header'},
{path: '', component: FooterComponent, outlet: 'footer'}
// Routes that display a header and footer go here.
]
},
{
path: '',
data: {header: false, footer: false},
children: [
{
path: 'frame',
children: [{
path: 'search',
loadChildren: () => import('./search/search.module').then(module => module.SearchModule)
}]
}
]
}
]
}
]
},
{
path: '**',
redirectTo: '/frame/search',
pathMatch: 'full'
}
];
By the way, using constants for defining the route props works if you compile with Ivy renderer.
I had the same error but yet another cause. I was dynamically assigning a key to the
routes
object:const routes: Routes = [{ path: '', component: SomeComponent, children: [{ path: 'blah', component: BlahCreateComponent, resolve: { [SOME_CONSTANT]: SomeResolver, // <-- you can't do this }, }], }]
I was only able to track down the issue by doing
ng build --prod --aot
which gave me an more descriptive error.
This should be working however, it is not so unusual to use constant keys for routing data that eventually you have to retrieve in other places of the application...
My workaround was something like this:
const routesData = {
data: {
[CONSTANT_1]: 'PARAM_VALUE_1',
[CONSTANT_2]: 'PARAM_VALUE_2'
}
}
const routes: Routes = [
{
path: 'myPath',
component: MyComponent,
...routesData,
// ... other routes configuration params
}
];
This actually works because the constant key values are resolved before the routes definition so there are no compilation errors.
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
_This action has been performed automatically by a bot._
Most helpful comment
I had the error. Found the cause in my case, want to share
in the TS app-routes module (of angular 5 project) I made a syntax error :
The error is the
at the end of the 4th line, which delivers an empty element in the Routes array, which delivers the loadChildren error.