How to have a sidenav with router-outlet and a separate login with router-outlet?

17,339

You will need two files with Routes. The first file will contain the pages without the navbar/sidebar.

app.routes.ts

    import { Routes } from '@angular/router';
    
    export const ROUTES: Routes = [
          {
            path: '', redirectTo: 'login', pathMatch: 'full'
          },
          {
            path: 'myApp', canActivate: [IsAuthorized], loadChildren: './layout/layout.module#LayoutModule'//<- Other routes here
          },
          {
            path: 'login', loadChildren: './login/login.module#LoginModule'
          },
          {
            path: 'error', component: ErrorComponent
          },
          {
            path: '**', component: ErrorComponent
          }
        ];

The Next file will contain the routes to other components or Modules.

layout.routes.ts

    import { Routes, RouterModule } from '@angular/router';
    import { LayoutComponent } from './layout.component';
    const routes: Routes = [
          { path: '', component: LayoutComponent, children: [
            { path: 'admin', loadChildren: '../admin/admin.module#AdminModule'},
            { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
            { path: 'home', loadChildren: '../home/home.module#HomeModule' },
            { path: 'about', loadChildren: '../about/about.module#AboutModule' }
          ]}
        ];
        export const ROUTES = RouterModule.forChild(routes);

layout.module.ts

    import { ROUTES } from './layout.routes';
    import { NavbarComponent } from './navbar/navbar.component';
    import { SidebarComponent } from './sidebar/sidebar.component';
    
    @NgModule({
      imports: [
        ROUTES
      ],
      declarations: [LayoutComponent, SidebarComponent, NavbarComponent
    })
    export class LayoutModule {
    }

Now in your layout.component.html file you will have the following layout.

layout.component.html

<app-custom-navbar></app-custom-navbar>
<app-custom-toolbar></app-custom-toolbar>
<app-custom-sidenav></app-custom-sidenav>
  <router-outlet></router-outlet>

app.module.ts

import { ROUTES } from './app.routes';
...
imports: [
    RouterModule.forRoot(ROUTES, {
      useHash: true,
      preloadingStrategy: PreloadAllModules
    })
  ],
...
export class AppModule { ... }

home.module.ts

export const routes = [
  { path: '', component: HomeComponent, pathMatch: 'full' }
];

NgModule({
  declarations: [
    HomeComponent
  ],
  imports: [
    RouterModule.forChild(routes),
  ]
})
export class HomeModule {
  public static routes = routes;
}

So now you can see that your AppModule will load the first app.routes.ts and take you to the login module. After the user logs in and is authenticated. You can redirect them to 'myApp/home'. This will trigger the HomeModule (that also has routes!) to load the HomeComponent.

Share:
17,339

Related videos on Youtube

Apostrofix
Author by

Apostrofix

Updated on July 05, 2022

Comments

  • Apostrofix
    Apostrofix almost 2 years

    I am trying to implement an app with a login page and then when the user is logged in, there would be a navbar, toolbar and sidenav that have a router-outlet.

    Basically, in the app.component.html I have a defined this:

    <div *ngIf="isAuthenticated">
      <app-custom-navbar></app-custom-navbar>
      <app-custom-toolbar></app-custom-toolbar>
      <app-custom-sidenav></app-custom-sidenav>
    </div>
    
    <router-outlet></router-outlet>
    

    And I have this routing:

    const routes: Routes = [
      { path: '', canActivate: [AuthenticationGuard], component: HomeComponent },
      { path: 'login', component: LoginComponent },
      {
        path: 'data',
        canActivate: [AuthenticationGuard],
        component: DataComponent,
      },
      {
        path: 'projects',
        canActivate: [AuthenticationGuard],
        component: ProjectsComponent,
      },
    ];
    

    So, this works well, if the user isn't authenticated, he gets redirected to /login.

    The problem is that when he is authenticated, the sidenav component takes the whole space and then the other components cannot be seen.

    Basically this is the problem:

    <mat-sidenav-container class="sidenav-container">
      <mat-sidenav>
        <!-- sidenav template... -->
      </mat-sidenav>
      <mat-sidenav-content>
        <!-- how can I put my content here and use routing at the same time ? -->
        <!-- <router-outlet></router-outlet> -->
      </mat-sidenav-content>
    </mat-sidenav-container>
    

    I thought about using aux routes, but then the routes are not user friendly. Instead I would like to keep them simple like:

    http://mywebsite.com/data
    http://mywebsite.com/login
    http://mywebsite.com/projects
    

    EDIT: The problem is solved now: Basically, I had to setup the routing properly. I needed to add main routing - e.g. login, logout and default route. And then I added my components as children items under the default route, which in my case is an empty '' path. That way my routes look clean and it looks the way I want it. I am editing my post with a link to a working example.

    Here is the URL to: stackblitz

    • darksoulsong
      darksoulsong over 6 years
      So, you ended up not using mat-sidenav?
  • Apostrofix
    Apostrofix over 6 years
    Thanks, this pointed me out to the right direction. Basically, I had to setup the routing properly. I needed to add main routing - e.g. login, logout and default route. And then I added my components as children items under the default route, which in my case is an empty '' path. That way my routes look clean and it looks the way I want it. I am editing my post with a link to a working example.