Create a simple CRUD app

Angular 15

Nested Routes

In this step-by-step tutorial you will learn how to create a multiview application using Angular 15, with custom ngModules (core, feature and shared), lazy loading, primary and nested routes

2022-02-25
6 min read
Difficulty
angular
typescript

TOPICS

Nested Routes

A primary route, just like /settings, can also define its own children and handle secondary routes:

  • /settings/profile
  • /settings/configuration
  • /settings/anything

Preview

Visit the "Settings" page to see the behaviors we're going to add:

So, create now the "Profile" page and define it as child of the Settings module (/settings/profile):

ng g m features/settings/profile --route profile --module features/settings.module

Do the same for the /settings/configuration page:

ng g m features/settings/configuration --route configuration --module features/settings.module

These commands have also updated the settings-routing.module file, adding two paths:

Angular
settings-routing.module
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SettingsComponent } from './settings.component';

const routes: Routes = [
  { path: '', component: SettingsComponent },
  // NEW
  { path: 'profile', loadChildren: () => import('./profile/profile.module').then(m => m.ProfileModule) },
  // NEW
  { path: 'configuration', loadChildren: () => import('./configuration/configuration.module').then(m => m.ConfigurationModule) }
];

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

Anyway, the default behavior is not what we really want.

In fact, the "Settings" page still works as before so, when we visit the http://localhost:4200/settings url, the default component is still loaded:

But the "default" component is totally destroyed (and the new one is loaded) when the /settings/profile page is visited.

And that's not what we want.

Our goal is the creation of a secondary navigation bar inside the default SettingsComponent to navigate the /profile and configuration pages.

3. Children Routes

Open features/settings/settings-routing.module.ts and move the paths you have just created as children of the route.

Angular
settings-routing.module
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { SettingsComponent } from './settings.component';

const routes: Routes = [
  {
    // the component loaded when `settings` page is visited
    // that contains a secondary Nav Bar and router-outlet
    path: '',
    component: SettingsComponent,
    // children routes
    children: [
      { path: 'profile', loadChildren: () => import('./profile/profile.module').then(m => m.ProfileModule) },
      { path: 'configuration', loadChildren: () => import('./configuration/configuration.module').then(m => m.ConfigurationModule) },
      // default path: automatically loads the '/profile' child route
      { path: '', redirectTo: 'profile', pathMatch: 'full' }
    ]
  },
];

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

We have also defined a default path to automatically redirect users to the /profile child route every time the /settings page is visited.

Add the secondary router-outlet

The primary component, SettingsComponent, acts now like the layout of the page and can contain a secondary navigation bar and another router-outlet that will be used to load and display its children routes.

So update SettingsComponent replacing all its content with the following:

Angular
features/settings/settings.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-settings',
  template: `
    <div class="btn-group">

      <button
        routerLink="./profile"
        routerLinkActive="text-bg-warning"
        class="btn btn-primary text"
      >Profile</button>

      <button
        routerLink="./configuration"
        routerLinkActive="text-bg-warning"
        class="btn btn-primary "
      >Configuration</button>

    </div>

    <router-outlet></router-outlet>
  `,
})
export class SettingsComponent { }

RESULT

You should be able to visit following children routes:

  • /settings (it automatically redirects to /settings/profile)
  • /settings/profile
  • /settings/configuration

Children routes are lazy loaded too!

Navigate between pages

You can also navigate between pages.

For example, we can add a button in ProfileComponent to redirect to the /configuration page.

Open settings -> profile -> profile.component.ts and add the button:

We use the routerLink directive to change the url

Angular
profile.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-profile',
  template: `
    <p>
      profile works!
    </p>
    <button
      routerLink="/settings/configuration"
      class="btn btn-outline-primary"
    >
      Go to configuration
    </button>
  `,
})
export class ProfileComponent {}

RESULT

Router API

We can also use the Router API, instead of the routerLink directive, in order to accomplish the same task.

Add a button in ConfigurationComponent to redirect to the /profile page:

Open features -> settings -> configuration -> configuration.component.ts, add a button and use the navigateByUrl method of Router service to redirect

Router service must be injected!

Angular
configuration.component.ts
import { Component } from '@angular/core';
import { Router } from '@angular/router';

@Component({
  selector: 'app-configuration',
  template: `
    <p>
      configuration works!
    </p>

    <button (click)="gotoProfile()" class="btn btn-outline-primary">
      Go to Profile
    </button>
  `,
})
export class ConfigurationComponent {
  constructor(private router: Router) { }

  gotoProfile() {
    this.router.navigateByUrl('/settings/profile');
  }
}

FINAL RESULT

Final Source Code

I hope you enjoyed the tutorial and that it was helpful.

You can find more Angular tutorials in the "Tutorials" section of this site.


ADS: MY LATEST VIDEO COURSE <br />(italian only)ADS: MY LATEST VIDEO COURSE <br />(italian only)
ADS: MY LATEST VIDEO COURSE
(italian only)
Keep updated about latest content
videos, articles, tips and news
BETA