Search code examples
angularangular2-routing

How to use Angular router outlet inside a component which itself is served via primary router outlet?


I am trying to make a router-outlet work inside DashboardComponent which itself is served via router-outler present in app.component.html.

The flow that I am trying to achieve goes like this:

  • After user logins, user is redirected to /dashboard which will load DashboardComponent.

  • DashboardComponent contains mat-sidenav-container with mat-sidenav links and a div container, inside which I have to serve different components - AComponent, BComponent, CComponent depending on the link clicked in mat-sidenav.

That is, path localhost:4200/dashboard/componentA should show AComponent in DashboardComponent 's div container and so on.

  • path /dashboard should redirect to /dashboard/componentA

I am having hard time trying to figure out how to show the components inside DashboardComponent using router-outlet.

Is this possible? Is there any better way to do this?

Working code

**app.routing.ts**

    import { Routes, RouterModule } from '@angular/router';
    import { HomeComponent } from './home/home.component';
    import { DashboardComponent } from './dashboard/dashboard.component';
    
    import { AComponent } from './a/a.component';
    import { BComponent } from './b/b.component';
    import { CComponent } from './c/c.component';
    
    export const appRoutes: Routes = [
        { path: '', component: HomeComponent },
        { path: 'dashboard', component: DashboardComponent, outlet: 'dashboard',
        children: [
            { path: '', component:  AComponent },
            { path: 'componentA', component:  AComponent },
            { path: 'componentB', component: BComponent },
            { path: 'componentC', component: CComponent }
           
          ]},
    
        // otherwise redirect to home
       //  { path: '**', redirectTo: '' }
    ];

Solution

  • What you have works, with a few modifications.

    Firstly, you don't need to assign a name to your router-outlet inside dashboard component. Named outlets have a different use case, you can read about them here:

    Here are the modifications you need to make

    1. Remove the outlet property from the dashboard route in app.routing.ts
    2. Remove the name directive from the router-outlet in dashboard.component.html
    3. Remove the 'dashboard/' from the [routerLink] in the a tags dashboard.component.html. Since these routes are children of the currently activated route, they their paths will automatically be appended after dashboard.
    //dashboard.component.html
    <mat-sidenav #sidenav align="start" position="start" mode="side"  opened="true" class="example-sidenav  side-nav-style">
      <ul>
        <li>
          <a [routerLink]="['componentA']">componentA</a>
        </li>
        <li>
          <a [routerLink]="['componentB']">componentB</a>
        </li>
        <li>
          <a [routerLink]="['componentC']">componentC</a>
        </li>
      </ul>
    </mat-sidenav>
    <div class="content">
      <p>dashboard works!</p>
      <router-outlet></router-outlet>          
    </div>
             
    //app.routing.ts
    children: [
      // { path: '', component:  AComponent },
      { path: 'componentA', component:  AComponent },
      { path: 'componentB', component: BComponent },
      { path: 'componentC', component: CComponent },
      { path: '', redirectTo: 'componentA', pathMatch: 'full'}
    ]},
    

    Additionally, notice I commented the first line in the children array and replaced it with a new one at the end. Using this approach, whenever the path is empty, it will automatically redirect to componentA and change the route as well, rather than just show componentA on an empty path.

    Updated code