How can I display a two-level nested component in Angular using the `router-outlet` feature?

Having a sidebar containing links at the /dashboard route, where these links serve as direct children to /dashboard. The goal is to render these children of /dashboard within the main router-outlet, but unsure of how to proceed. Below are code snippets illustrating the issue:

Reviewing the Routing Structure

const routes: Routes = [
  {
    path: '',
    component: LoginComponent,
  },
  {
    path: 'dashboard',
    component: DashboardComponent,
    children: [
      {
        path: 'roles',
        component: RolesComponent,
      },
      {
        path: 'workgroups',
        component: WorkgroupsComponent,
        children: [
          {
            path: 'savewg',
            component: WgDetailsComponent,
          },
        ]
      },
      {
        path: 'users',
        component: UsersComponent,
      },
    ],
  },
];

Main App Component Structure

<!-- Main app component -->
<div class="app-view">
 <router-outlet></router-outlet>
</div>

Login.html Implementation

<button mat-raised-button color="warn" class="login-field" (click)="login(email, password)"
            <!-- rest of the code omitted for brevity  -->

Login.ts Functionality

public login(email: string, password: string) {
    this.router.navigate(['dashboard'], { replaceUrl: true });
  }

Workgroup Component HTML Section

    <button mat-raised-button color="warn" [routerLink]="['savewg']">
            <mat-icon>add</mat-icon>
              New
        </button>
       <!-- Code omitted for brevity ... -->

<router-outlet></router-outlet>
<div class="workgroup-filters">
<mat-form-field appearance="outline">
    <!-- remaining code omitted for brevity -->
  • Desiring the ability for the New button in the workgroup component to navigate to the savewg component view and replace the content within the workgroup component.
  • Grateful for any suggestions on addressing this challenge.

Answer №1

In each module, only one main router-outlet is allowed. To handle multiple routes for different functionalities, you need to create a separate module specifically for the workgroups path and lazy load it. This new module will have its own routing file defining all the routes related to workgroups, as well as its own router outlet where these routes will be loaded from the workgroup module. Check out the working example provided below.

app-routing.module.ts

const routes: Routes = [
  ...
  {
    path: 'workgroups',
    loadChildren: () => import('./workgroups/workgroups.module').then(m => m.WorkgroupsModule)
  },
  ...
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

workgroups-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: WorkgroupsComponent,
    children: [
      {
        path: 'savewg',
        component: WgDetailsComponent
      },
      {
        path: '**',
        redirectTo: 'savewg',
        pathMatch: 'full'
      }
    ]
  },
  
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class WorkgroupsRoutingModule { }

workgroups.module.ts

@NgModule({
  imports: [
    CommonModule,
    WorkgroupsRoutingModule
  ],
  declarations: [
    WorkgroupsComponent, 
    WgDetailsComponent
    ]
})
export class WorkgroupsModule { }

For more information on lazy loading modules and to see a demonstration, refer to the resources and stackblitz example provided below.

https://stackblitz.com/edit/angular-ivy-hbogtn

Answer №2

After some exploration, I came across a more efficient solution for this issue. It appears that Angular automatically interprets the empty path route as the default route, eliminating the need to concern ourselves with router outlet any longer. To implement this change, I made adjustments to my app-routing.module.ts:

const routes: Routes = [
  {
    path: '',
    component: LoginComponent,
  },
  {
    path: 'dashboard',
    component: DashboardComponent,
    children: [
      {
        path: 'roles',
        component: RolesComponent,
      },
      {
        path: 'workgroups',
        children: [
          {
            path: 'savewg',
            component: WgDetailsComponent,
          },
          {
            path: '',
            component: WorkgroupsComponent,
          },
        ],
      },
      {
        path: 'users',
        component: UsersComponent,
      },
    ],
  },
];
  • By including an empty path as a child in the workgroups component, I've attained a viable workaround for now. Nevertheless, I remain open to discovering additional methods and solutions.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to calculate the total number of keys within a JSON object at a certain level

I need to process a JSON file by extracting values from keys located at a specific depth. The initial value I want to access is situated here: json.children[0].children[0].children[0] Is there a method to navigate through the JSON object at a particular ...

In the XHTML mode, MathOverflow's invaluable mathematical expertise shines brightly

I am interested in incorporating the unique “piece of valuable flair™” from MathOverflow onto my website. The issue I am facing is that I want my webpage to comply with XHTML5 standards, meaning it should be served with the MIME type application/xht ...

Refreshing a Next.js website on-demand using the Django model's save function

My current setup involves a next.js website deployed on Vercel, which retrieves data from an API provided by Django. Utilizing a new feature in Next.js known as Incremental Static Regeneration On-Demand, I am able to rebuild specific pages without having t ...

JavaScript - Saving an array of objects to an .xlsx file with various header rows that are merged

I am faced with the challenge of recreating an Excel file that was manually created programmatically. I currently have a node.js(TS) service that exports data into a csv file, but the formatting is not as desired. After some research, I couldn't find ...

Could someone assist me in resolving the issue of receiving empty emails from my online form submission?

Every day, I receive 6 blank emails from my contact form at the same time. Even though the form on the website is filled out correctly and all the information goes through, I still get these mysterious blank emails. I have implemented validation checks in ...

What is the best way to iterate through a JSON associative array using JavaScript?

When I receive a JSON response from the server, my goal is to loop through the array in JavaScript and extract the values. However, I am facing difficulties in doing so. The structure of the JSON response array is as follows: { "1": "Schools", "20" ...

The correct method for handling arrays with overlapping types and narrowing them down again

When working with arrays containing different types in TypeScript, I often encounter issues with properties that are not present on all types. The same challenge arises when dealing with various sections on a page, different user roles with varying proper ...

What is the best way to retrieve selected text in an editor from an external source?

Is there a way to retrieve selected text from an editor that was originally highlighted outside of the editor? I have tried using editor.getSelection().getSelectedText() but it doesn't seem to be working. Any suggestions on how to accomplish this? ...

What is the best method for efficiently loading SVG icons on an HTML page without redundancy? / Is utilizing <use href> recommended?

My struggle with implementing icons in Angular While working on a new Angular project, I've encountered challenges with my current SVG-icon implementation method from a previous project (@ngneat/svg-icon). The process involves organizing SVG files in ...

Conceal a Component within an Embedded Frame

Hey there! I've been attempting to hide a header within an iframe, but it seems like my code isn't doing the trick. Could someone take a look and help me diagnose why the header is still visible? Thanks in advance! <iframe id="booking_iframe" ...

What's the reason behind JavaScript's Every method not functioning properly?

I'm struggling to understand why the array method 'every' is not functioning properly in my project (working on a roguelike dungeon crawler game). Here's an example of the array of objects I am working with: { x: newrm.x, ...

Verifying credentials using Chromium pop-up window with Playwright

In my current project, I am using Playwright to automate the configuration of multiple devices. However, I have encountered a challenge with certain models that require authentication through a popup dialog box in Chrome. https://i.stack.imgur.com/jgnYM.p ...

The issue is that the JavaScript output is not being displayed after submitting the HTML

I'm looking to add not only a submit button for the default form action, but also an extra button for a second action. Here is the code I have so far: <html> <head><title></title> <?PHP $Input = ""; if(isset($_POST['I ...

Tips for Creating an Upward-Dropping Dropdown Menu in HTML/JavaScript When Space is Limited on the Page

Hello, I am currently seeking a solution to adjust my dropdown menu so that it appears above instead of below when the page doesn't have enough space to display it fully. My tools for this project include HTML, Javascript, CSS, and JQuery exclusively. ...

Establishing a path for a post request in a Node.js application

While setting up a basic registration page, I encountered an error when trying to establish a route for the post request of the user credentials. node:_http_outgoing:648 throw new ERR_HTTP_HEADERS_SENT('set'); ^ Error [ERR_HTTP_HEADERS_ ...

Activate a jQuery collapsible feature through an external hyperlink

Can we enable the expansion of a jQuery collapse by clicking on an external link? For instance, let's say we have a link on the home page that leads to another page. When the user clicks on this link from the home page, we want it to redirect to the i ...

Keeping Record of Assurances

I'm currently working on a project where I need to track Promises effectively. Within the project, there are some lingering async tasks that haven't been properly awaited or yielded. Identifying and addressing these cases is crucial as they are ...

What could be causing my createElement to double in reactjs useEffect()?

My current dilemma is rather straightforward, focusing solely on the useEffect() parts without delving into the other codes. Whenever I hover over the text, my custom mouse cursor text ends up doubling. Here are the code snippets: const cursorIntro = ...

Obtain additional information to address concerns related to onZoom and onPan issues on the line

Attempting to enhance my Chart.js line chart by fetching more data or utilizing cached backup data during onZoom/onPan events has proven quite challenging. The original code base is too intricate to share entirely, but I will outline the approaches I have ...

Error encountered when initializing a variable within the constructor of a TypeScript file in Angular 4

This is the content of my app.component.html file PL Auth Username: Password : Generate OTP Enter OTP : Login This is the code in my app.component.ts file import { Component, OnInit } from '@angular/core' ...