angular: Creating ROUTES with custom factory function ends up with "Cannot read property 'loadChildren' of undefined" error
I’m submitting a…
[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report <!-- Please search GitHub for a similar issue or PR before submitting -->
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
When angular compiler finds a provider that defines ROUTES
, but which doesn’t have a useValue
property, (because it has f.e. useFactory
property instead) it fails with the following error:
ERROR in TypeError: Cannot read property 'loadChildren' of undefined
at _collectLoadChildren (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@angular/compiler/bundles/compiler.umd.js:29034:20)
at listLazyRoutes (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@angular/compiler/bundles/compiler.umd.js:29009:49)
at AotCompiler.listLazyRoutes (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@angular/compiler/bundles/compiler.umd.js:31150:51)
at AngularCompilerProgram.listLazyRoutes (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@angular/compiler-cli/src/transformers/program.js:156:30)
at AngularCompilerPlugin._listLazyRoutesFromProgram (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:304:38)
at Promise.resolve.then.then (/Users/jtomaszewski/src/recruitee/rails/admin_app/node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:583:50)
at process._tickCallback (internal/process/next_tick.js:109:7)
webpack: Failed to compile.
Expected behavior
Defining a provider for ROUTES
with other providers like f.e. FactoryProvider
should just work.
Minimal reproduction of the problem with instructions
- Write your module like this:
import { NgModule, NgModuleFactory, Compiler } from '@angular/core';
import { Routes, RouterModule, ROUTES } from '@angular/router';
export function MainRoutingLazyRoutesFactory(compiler: Compiler): Routes {
return [
{
path: 'dashboard',
loadChildren: () => {
return <any>System.import('../features/dashboard/dashboard.module')
.then(({ DashboardFeatureModule }) => DashboardFeatureModule)
.then(ngModule => {
if (ngModule instanceof NgModuleFactory) {
return ngModule;
} else {
return compiler.compileModuleAsync(ngModule);
}
});
},
},
];
}
@NgModule({
imports: [RouterModule],
exports: [RouterModule],
providers: [
{
provide: ROUTES,
multi: true,
deps: [Compiler],
useFactory: MainRoutingLazyRoutesFactory,
},
],
})
export class MainRoutingModule {}
- Try to compile it, in either JiT or AoT mode.
What is the motivation / use case for changing the behavior?
It lets you to easily implement lazy loaded modules in your routes with your custom way.
Environment
node 6.11.5
npm 5.6.0
angular 5.2.8
@ngtools/webpack 1.10.2
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 13
- Comments: 20 (4 by maintainers)
For me it consistently fails on run of
ng serve
but every next recompilation (on file save) is successful.I am not quite sure if that is related to this exact issue, but this might just be an issue with anonymous functions in route objects, i found a solution on stackoverflow that worked for me, having a similar setup: https://stackoverflow.com/a/48205304/3880255.
Changing the anonymous functions to named functions fixed the error, i sadly have no insight on why tho, might be worth a try.
I experienced the same behavior as @DominikDitoIvosevic . I was able to solve the issue, i.e. make it not fail on
ng serve
by exporting my factoring function. Below is my simplified setup (No lazy loading involved).my-routing.module.ts:
Same problem, but the fix for me was: { provide: ROUTES, multi: true, deps: [ModuleLoaderService, Compiler], useValue: {}, // Can’t compile when not defined useFactory: LazyRoutesFactory }
I’ve followed through the stack trace and think I’ve found what causes the bug:
I think it’s because of this code in the angular/compiler’s source:
According to the stacktrace, it fails on
_collectLoadChildren(provider.useValue);
.Obviously, this provider has no
useValue
. IMHO we should skip parsing it, if it doesn’t have such a property.P.S. We’ve submitted this issue on angular-cli first ( https://github.com/angular/angular-cli/issues/9913 ) but they redirected us here.
P.S.2. In the meantime, we’ve managed to build a workaround to make it compile anyway:
@jasonaden I am getting the same error but with a different case scenario. I don’t know if this is related with angular or webpack cli.
My issue seems to be related with using an object initializer in a route object. Here an example code https://stackblitz.com/edit/angular-nxvknf. I am using a ‘test’ key inside app routes and seems like it is working using stackblitz.
When using webpack to compile, it is not working. It is calling _collectLoadChildren with provider.useValue, that is undefined in this case. If i switch the data property to a string, it works. Another strange thing is that it only happens when it compiles the first time. If i save with live reloading it is compiled successfully.
Do you think that they could be related?
ivy fix the bug.
I am facing same issue but unable to resolve with the given solution. I am using below configuration
As @DominikDitoIvosevic mentioned, for me it was failing on the first
but doing just a simple change in code, anywhere, and saving fixed the issue. Sadly it was further failing on Jenkins.
Solution in my case was ridiculous: It was specifically related to a feature module routing module which was lazy loaded.
This was failing:
This was working:
Ridiculous, but if this helps someone…
I’m experiencing the same error even after enabling ivy.
Also, as @DominikDitoIvosevic said, the error shows up consistently only on the first iteration
ng serve
building