Search code examples
javascriptangularangular-routing

Angular Nested Named Outlets Routes


Hello im trying to nest my outlet routes in angular 9. whenever i go to http://localhost:4200/app/(orders:orders)/(order-details:/order-details) i get redirected to http://localhost:4200/app/(orders:orders)

im trying to have a view where they can see a list of the orders, then when clicked on orders display another view with order details. thanks for help

routes.ts

const routes: Routes = [
  { path: '', component: LoginComponent },
  {
    path: 'app',
    component: HomeComponent,
    runGuardsAndResolvers: 'always', canActivate: [AngularFireAuthGuard],
    children: [
      {
        path: 'orders', component: OrdersComponent, outlet: 'orders',
        children: [
          {
            path: 'order-details', component: OrderDetailsComponent, outlet: 'order-details',
          }
        ]
      }
    ]
  },
  { path: '**', redirectTo: '', pathMatch: 'full' }
];

home.component.html

<mat-drawer-container class="example-container">
    <mat-drawer mode="side" opened>
        Drawer content
        <button (click)="signOut()">signout</button>
    </mat-drawer>
    <mat-drawer-content>
        <p>hello</p>
        <router-outlet name="orders"></router-outlet>
        <router-outlet name="order-details"></router-outlet>
    </mat-drawer-content>
</mat-drawer-container>

orders.component.ts

<div>
    <ul>
        <li *ngFor="let order of orders | async">
            {{ order.id }} status is: {{order.status}}
            <button (click)="confirmOrder(order)">confirm order</button>
        </li>
    </ul>
    <router-outlet name="order-details"></router-outlet>
</div>

Solution

  • After Too Much Effort I got the Solution :-

    Solution URL :- /app/(orders:orders/(order-details:order-details))

    Working Stackblitz :- https://stackblitz.com/edit/angular-oac197

    Route Config :-

    RouterModule.forRoot([
          { path: "", component: LoginComponent },
          {
            path: "app",
            outlet: "primary",
            component: HomeComponent,
            children: [
              {
                path: "orders",
                outlet: "orders",
                component: OrdersComponent,
                children: [
                  {
                    path: "order-details",
                    component: OrderDetailsComponent,
                    outlet: "order-details"
                  }
                ]
              }
            ]
          },
          { path: "**", redirectTo: " ", pathMatch: "full" }
      ]
        )
    

    app.component.html

    <div class="example-container">
        <div mode="side" opened>
            Drawer content
            <button (click)="signOut()">signout</button>
        </div>
        <div>
            <p>hello</p>
        </div>
    </div>
    <router-outlet></router-outlet>
    <button (click)="navigateToOrders()"> Go To Order </button>
    <button (click)="navigateToOrderDetails()">Go To Order Details</button>
    

    app.component.ts

    import { Component } from "@angular/core";
    import { Router } from "@angular/router";
    
    @Component({
      selector: "my-app",
      templateUrl: "./app.component.html",
      styleUrls: ["./app.component.css"]
    })
    export class AppComponent {
      name = "Angular";
      constructor(private router: Router) {}
      public navigateToOrders() {
        this.router.navigate(["app", { outlets: { orders: ["orders"] } }]);
      }
    
      public navigateToOrderDetails() {
        this.router.navigate(["app",{ outlets: {orders: ["orders", {outlets: {"order-details": ["order-details"] }}]}  }]);
      }
    }
    

    home.component.html

    <router-outlet name="orders"></router-outlet>
    

    orders.component.html

    <p>
    orders works!
    </p>
    
    <router-outlet name="order-details"></router-outlet>
    

    order-details.component.html

    <p>
    order-details works!
    </p>