Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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: '' }
    ];
like image 209
devN Avatar asked Nov 02 '17 11:11

devN


People also ask

Can we use multiple router outlet in Angular?

You can have multiple router-outlet in same template by configuring your router and providing name to your router-outlet, you can achieve this as follows. Advantage of below approach is thats you can avoid dirty looking URL with it.

How would you use a router outlet to display a view in Angular?

Router-outlet in Angular works as a placeholder which is used to load the different components dynamically based on the activated component or current route state. Navigation can be done using router-outlet directive and the activated component will take place inside the router-outlet to load its content.

What is router-outlet in angular?

Router-Outlet In Angular. Router-outlet in Angular is used to load the different components based on the router status, or we can say that it acts as a placeholder to load the dynamic components based on the activated route.

How does the router find the right component in a route?

This is the complete syntax, what we saw earlier was some syntactic sugar for the most common case of the primary outlet. This time, we tell the router which outlet is concerned by the route, and we give it the path. From this, the router finds the route, and displays the right component in our secondary outlet.

How to use the router-outlet directive in angular?

To tell Angular what to do with the component the router gives us, we use the router-outlet directive. It is a placeholder that marks the spot where this component should be displayed. In our case, right under the buttons. We can now see the list being updated when we click on a button. We now want to allow the user to add items to a grocery list.

What is an auxiliary route in angular 9?

This route is called an auxiliary route because it's mapped to the secondary outlet. Routes that are mapped to the primary outlet are called primary routes. In this quick post we have seen what a router outlet is in Angular 9, and how to name and create multiple outlets.


3 Answers

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

like image 133
Aamir Khan Avatar answered Oct 19 '22 10:10

Aamir Khan


You basically have two routes pointing out to the same component.

{ path: '', component: DashboardComponent },
{ path: 'dashboard', component: DashboardComponent, }

You should use redirect to achieve your desired behavior. And in your dashboard.html - links to child components are absolute - it breaks the navigation anyway in your case - consider to use relative links. You don't need to specify a name of route outlet in this case as well - will work out of the box with proper routing setup. Once i fixed all of the above - navigation started to work.

See code samples below:

app.routing.ts

 export const appRoutes: Routes = [
{ path: '', pathMatch: "full", redirectTo: 'dashboard' },
{
   path: 'dashboard', 
    component: DashboardComponent ,
    children: [
    { path: 'componentA', component:  AComponent },
    { path: 'componentB', component: BComponent },
    { path: 'componentC', component: CComponent }

  ]},

];

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>
like image 44
n.yakovenko Avatar answered Oct 19 '22 10:10

n.yakovenko


I have made some modifications to your routing file and the dashboard component file.

First you don't need to use named routes. Secondly children routes take their parents initial path so no need to provide them again and you can directly specify the child route name in router link.

you can check the working code here

working code

hope this solves your issue.

like image 1
Gautam Avatar answered Oct 19 '22 11:10

Gautam