Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Angular, how I navigate directly to a path inside a lazy loaded module?

I would like to have two top level paths for logging in and registering.

I would prefer not having to do auth/log-in and auth/register.

However, the auth components are in a separate module, which is good because it shouldn't be loaded unless specifically requested.

export const routes: Route[] = [
  { path: 'log-in',   loadChildren: './auth-module/auth.module#AuthModule'},
  { path: 'register', loadChildren: './auth-module/auth.module#AuthModule'}
];

How can I specify when I am defining my routes that I want the log-in path to go to the log-in path inside the lazy loaded AuthModule, and the register path to go to the register path inside the lazy loaded module?

like image 842
CodyBugstein Avatar asked Mar 30 '18 01:03

CodyBugstein


People also ask

Which route property should be used to load a module lazily?

To lazy load Angular modules, use loadChildren (instead of component ) in your AppRoutingModule routes configuration as follows. content_copy const routes: Routes = [ { path: 'items', loadChildren: () => import('./items/items. module'). then(m => m.

How do you use a lazy load module without routing?

define where we want to load our component in the template with the ng-template tag, define its view query through ViewChild decorator, which gives us access to the DOM and defines the container to which the component will be added, finally, dynamic import the component and add it to the container.

Which is the dynamic import syntax to lazy load a module in route?

New with Angular 8, loadChildren expects a function that uses the dynamic import syntax to import your lazy-loaded module only when it's needed. The dynamic import is promise-based and gives you access to the module, where the module's class can be called.

How lazy loading works internally in Angular?

Lazy loading is a useful technique for faster initial page loads. With lazy loading, your application loads faster by shipping only the essential startup code to the browser. Another code is placed inside of feature modules, which are loaded on demand. Lazy loading is a useful technique for faster initial page loads.


1 Answers

Update

It is possible, even for lazyloaded modules to define an empty route.

const APP_ROUTES: Routes = [
    { path: '', () => import('./app/auth/auth.module').then(m => m.AuthModule)},
];

And in your lazy loaded module define the path for both components

const MODULE_ROUTES: Routes = [
    { path: 'login', component: LoginComponent},
    { path: 'register', component: RegisterComponent }
];

The module is only loaded when a component path is matched

Original Awnser

Up to now it is not possible to configure routes as you wanted to do in your post. You can see that if you enable logging for your router. The path for your module (login, register) is consumed and in your module routing you'll just have '' left, which can not be matched to two different components.

You can achive this none the less, even if it's not that pretty and I don't know how/if it works in older browsers.

In your app.module.ts

const APP_ROUTES: Routes = [
    { path: 'login', redirectTo: 'auth/login', pathMatch: 'full' },
    { path: 'register', redirectTo: 'auth/register', pathMatch: 'full' },
    { path: 'auth', loadChildren: 'app/auth/auth.module#AuthModule', pathMatch: 'prefix'},
];

@NgModule( {
    declarations: [
        AppComponent
    ],
    imports: [
        BrowserModule,
        RouterModule,
        RouterModule.forRoot(APP_ROUTES)
    ],
    providers: [
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

and the auth.module.ts looks like this

const ROUTES: Routes = [
    { path: 'login', component: LoginComponent, pathMatch: 'full' },
    { path: 'register', component: RegisterComponent, pathMatch: 'full' }
];

@NgModule( {
    imports: [
        CommonModule,
        RouterModule.forChild( ROUTES )
    ],
    declarations: [
        LoginComponent,
        RegisterComponent
    ]   
} )
export class AuthModule { }

You can then access the routes by <a routerLink="login">Login</a>, works with router.navigate as well. Unfortunally this will leave you with auth/login or auth/register in your browsers url even if the client calls just /login.

You can fix that by creating an entry in your window.history - as I said not to pretty and that has to be done in your components constructor. window.history.pushState('register', 'Register', 'register'); or window.history.pushState('login', 'Login', 'login'); in the components will leave your browsers url with /login and /register.

The best way would of cause be to extend the angular router with this functionallity and use that as custom router, but you'd have to get really into it for that and with the next update you might get screwed.

Maybe this helps you

Best regards

like image 53
Fussel Avatar answered Oct 10 '22 22:10

Fussel