import {NgModuleFactoryLoader} from '@angular/core';
import {AsyncNgModuleLoader} from './async-ng-module-loader';
// Add to main providers
{provide: NgModuleFactoryLoader, useClass: AsyncNgModuleLoader}
-
-
Save brandonroberts/02cc07face25886fe142c4dbd8da1340 to your computer and use it in GitHub Desktop.
import {Injectable, NgModuleFactory, NgModuleFactoryLoader, Compiler, Type} from '@angular/core'; | |
class LoaderCallback { | |
constructor(public callback) {} | |
} | |
export let load: Type = (callback: Function) => { | |
return new LoaderCallback(callback); | |
}; | |
/** | |
* NgModuleFactoryLoader that uses Promise to load NgModule type and then compiles them. | |
* @experimental | |
*/ | |
@Injectable() | |
export class AsyncNgModuleLoader implements NgModuleFactoryLoader { | |
constructor(private compiler: Compiler) {} | |
load(modulePath: string|LoaderCallback): Promise<NgModuleFactory<any>> { | |
if (modulePath instanceof LoaderCallback) { | |
let loader = (modulePath as LoaderCallback).callback(); | |
return Promise | |
.resolve(loader) | |
.then((type: any) => checkNotEmpty(type, '', '')) | |
.then((type: any) => this.compiler.compileModuleAsync(type)); | |
} | |
return Promise.resolve(null); | |
} | |
} | |
function checkNotEmpty(value: any, modulePath: string, exportName: string): any { | |
if (!value) { | |
throw new Error(`Cannot find '${exportName}' in '${modulePath}'`); | |
} | |
return value; | |
} |
I notice: in my project there two modules with children module integration. Webpack build without errors but I find two new *.js files in root folder: 1.js and 4.js Should I import this files into project befor publish or this files imported into main.js......?
I have some difficulties with location were I should register provider. So for others who try implemet this solution...in app.module.ts
:
providers: [
{ provide: NgModuleFactoryLoader, useClass: AsyncNgModuleLoader },
...
]
i the routermodule
DarienF, put it in the router module.
EXCEPTION: Error: Uncaught (in promise): TypeError: loadChildren is not a function
I got error like this... ^
do I miss something?
at app.routing.ts
const routes: Routes = [
{
path : 'dev',
loadChildren: load(() => new Promise(resolve => {
return (require as any).ensure([], (require: any) => {
return resolve(require('./pages/dev/dev.module').default);
});
}))
},
{
path : '',
component: HomeComponent
}
];
at app.module.ts
providers : [
{provide: NgModuleFactoryLoader, useClass: AsyncNgModuleLoader},
AuthGuard,
SessionService,
],
Hello @brandonroberts,
I'm having same issue as @lialosiu, can you please provide some advise?
Thank you,
Laurentiu
loadChildren: () => new Promise(resolve => {
return (require as any).ensure([], (require: any) => {
return resolve(require('./pages/dev/dev.module').default);
});
})
did the trick for me. Notice the absence of load()
@forsak3n yes, that will work once RC6 lands and you won't need the loader anymore at all 😄
it's work, awesome gist. more thanks for you. 👍
I get a "Generic type 'Type' requires 1 type argument(s)." after upgrading to rc6. Replacing Type
by Type<any>
won't fix it.
Just tried @forsak3n s' solution, my routes is like
export const loginRoutes: Routes = [
{
path: 'login',
loadChildren: () => new Promise(resolve => {
return (require as any).ensure([], (require: any) => {
return resolve(require('./login.module/login.module').LoginModule);
});
})
}];
export const loginRouting = RouterModule.forChild(loginRoutes);
then, I get "Type '() => Promise<{}>' is not assignable to type 'string'."
The following works for my startup in RC6:
{ path: 'task2', loadChildren: () =>
new Promise(resolve =>
(require as any).ensure([], () =>
resolve(require('./task-2/task2.module').Task2Module)
)
)
}
@AnotherStop, have you updated your typings.json
?
Hi @iurii-kyrylenko,
Can you please help me a bit as I'm out of solutions. I have tried your solution but I'm getting "No NgModule metadata found for '[object Promise]'" error. I want to mention that I don't use Typescript. I have placed bellow the code I'm using:
- router
{
path: 'style-guide',
loadChildren: () =>
new Promise(resolve => {
return require.ensure([], () =>
resolve(require('./style-guide.module').StyleGuideModule)
);
}
-style guide module
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import StyleGuideComponent from './style-guide.component';
@NgModule({
imports: [
CommonModule,
RouterModule.forChild([
{ path: '', component: StyleGuideComponent }
])
],
declarations: [
StyleGuideComponent
]
})
export class StyleGuideModule {}
Thank you,
Laurentiu
@iurii-kyrylenko I am transpiling my code with babel and I m using a decorator plugin. That s why I can use decorators without Typescript and I don t have a tsconfig file.
Thank you
Laurențiu
the same issue with @lialosiu
@qk44077907 @lialosiu are you still having this issue? With RC6 you don't need a custom loader anymore. I also have a webpack loader here you can use if you want to use string-based lazy loading: https://www.npmjs.com/package/angular2-router-loader
hello can anyone help me,
Work this issue with RC5.
{
path: 'admin',
loadChildren: load(() => new Promise(resolve => {
return (require as any).ensure([], (require: any) => {
return resolve(require('./pages/dev/dev.module').default);
});
}))
},
because of require cannot find name.
export let load: Type = (callback: Function) => {
return new LoaderCallback(callback);
};
Generic type 'Type' requires 1 type argument(s)
Getting above error while compile with ng serve
node -v 7.0.0
npm -v 3.10.8
angular-cli: 1.0.0-beta.19-3
editor : Visual Studio Code
please help me...
"dependencies": {
"@angular/common": "~2.1.0",
"@angular/compiler": "~2.1.0",
"@angular/core": "~2.1.0",
"@angular/forms": "~2.1.0",
"@angular/http": "~2.1.0",
"@angular/platform-browser": "~2.1.0",
"@angular/platform-browser-dynamic": "~2.1.0",
"@angular/router": "~3.1.0",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"jquery": "^3.1.1",
"rxjs": "5.0.0-beta.12",
"ts-helpers": "^1.1.1",
"zone.js": "^0.6.23"
},
Same error than @masagatech trying to fix it right now.
same error @masagatech trying to fix it right now
Works Perfect! Awesome work!