Angular switch from lazyLoading to 'normal' loading
Asked Answered
W

2

16

I am working on an Angular application that has lazy loading implemented. I tried experimenting with lazy loading but decided that I do not yet want to implement it in my application. This is my app.module.ts:

app.module.ts:

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    RouterModule.forRoot([
      { path: '', redirectTo: 'store', pathMatch: 'full'},
      { path: 'hq', loadChildren: 'app/hq/hq.module#HqModule' },
      { path: 'store', loadChildren: 'app/store/store.module#StoreModule', pathMatch: 'prefix'},
    ]),
  ],
  bootstrap: [AppComponent],
  exports: [RouterModule],
})
export class AppModule { }

How can I switch my route to for example hq back to normal loading? I expected that something as follows would work:

{ path: 'hq', redirectTo: HqModule }

That however returns that my module is a wrong type of argument. Is this even possible in Angular?

hq.module.ts

@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild([
        { path: '',
          component: HqTemplateComponent,
          canActivate: [AuthGuard],
          children: [
            { path: '', pathMatch: 'full', redirectTo: 'overview' },
            { path: 'overview', component: OverviewComponent, canActivate: [AuthGuard] },
          ]
        },
    ]),
  ],
  declarations: [HqTemplateComponent, OverviewComponent]
})
Wheelock answered 8/10, 2017 at 1:3 Comment(0)
A
10

Arrow function

I like doing it by changing string to arrow function looking something like:

import { HqModule } from './hq/hq.module';


{ path: 'hq', loadChildren: () => HqModule },

for aot angular 4 and less:

export function loadHqModuleFn() {
  return HqModule;
}

{ path: 'hq', loadChildren: loadHqModuleFn },

Note: Beginning in version 5, the compiler automatically performs this rewritting while emitting the .js file. Thanks to "expression lowering"

Plunker Example

angular-router-loader?sync=true

If you use angular-router-loader then you should be aware that this loaded has special syntax for to load module synchronously. Just add the sync=true as a query string value to your loadChildren string:

{ path: 'hq', loadChildren: 'app/hq/hq.module#HqModule?sync=true' },

imports

Of course you can just add module to imports array but in this case you have to change router config path for this module:

app.module.ts

@NgModule({
  imports: [
    ...,       
    HqModule,
    BrowserModule,
    RouterModule.forRoot([
      { path: '', redirectTo: 'store', pathMatch: 'full'},
      { path: 'store', loadChildren: 'app/store/store.module#StoreModule', pathMatch: 'prefix'},
    ])
  ]
  ...
})
export class AppModule {}

hq.module.ts

@NgModule({
  imports: [
    ...
    RouterModule.forChild([
        { path: 'hq', <========================== changed '' to `hq`
          component: HqTemplateComponent,
          canActivate: [AuthGuard],
          children: [
            ...
          ]
        },
    ]),
  ],
  ...
})

It's also worth mentioning that angular router config is strict about order. According to the docs:

The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes

So add modules with routes definition to imports array in the same order as if you would do it in RouterModule.forRoot.

Acceptant answered 8/10, 2017 at 4:5 Comment(1)
I am trying to get your arrow working solution up and running, it doesn't work for my angular-cli instance: ERROR in Error: Error encountered resolving symbol values statically. Function calls are not supported. Consider replacing the function or lambda with a reference to an exported function (position 27:38 in the original .ts file), resolving symbol AppModule in /project/project-frontend/src/app/app.module.tsWheelock
C
1

Add HqModule to your AppModule's import array and remove HqModule entry from the AppModule routing definition. Like this:

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    HqModule, // add it
    RouterModule.forRoot([
      { path: '', redirectTo: 'store', pathMatch: 'full'},
      { path: 'store', loadChildren: 'app/store/store.module#StoreModule', pathMatch: 'prefix'}
    ])
  ],
  bootstrap: [AppComponent],
  exports: [RouterModule],
})
export class AppModule { }
Curagh answered 8/10, 2017 at 2:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.