Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Les't learn/explore the foundations of Angular Routing and create practical real-world Single Page Application - SPA.

Notifications You must be signed in to change notification settings

dinanathsj29/angular-routing-and-navigation-tutorial

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

22 Commits

Repository files navigation

angular logo

Working with Angular Routing and Navigation

Working with existing/cloned/copied Angular App

  • Clone or Download the project/app from Github or any other sources
  • If using Visual Studio Code / Insiders, open Command panel/terminal from menu: View -> Terminal (shortcut key is CTRL + BackTick OR COMMAND + J)
  • Go inside the project/app directory, command: cd _examples-angular6-2-routing OR cd appName
  • Run command: npm install to install project/app dependencies (node_modules)
  • To Build and run Angular App, command: ng serve / npm start OR ng serve -o OR ng serve --open
  • To change port from 4200 to other port - type command: ng serve --port 5000
  • To check the application in browser type path/url: localhost:4200 / 5000

1 Angular Routing and Navigation

  • The Angular Router enables navigation from one view (component) to the another/next as users perform tasks, views (component)
  • Routing simply means navigating between different view (component)
  • RouterModule
    • RouterModule helps to create routes, which allows us to move from one part of the application to another part or from one view to another
    • A separate NgModule/Angular Module that provides the necessary service providers and directives for navigating through application views
  • Router
    • The Angular Router is an optional service that presents a particular component view for a given URL, it is not part of the Angular core
    • The Angular Router enables navigation from one view to the another as users perform application tasks/actions
  • router-outlet
    • The directive (<router-outlet>) that marks where the router displays a view (a container to hold different views/components loaded as users perform application tasks/actions)
  • routerLink
    • The attribute/directive for binding a clickable HTML element to a route which denotes link/view name to load/show in (<router-outlet>)

Let's create below Angular Single Page Application (SPA) with Routing and Navigation feature:

Image - Output - Angular Single Page Application (SPA) with Routing and Navigation - Home View

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Home View

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Departments View

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Departments View

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Employees View

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Employees View

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Products View

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Products View

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Folder structure

Image - Output - Angular Single Page Application (SPA) with Routing Navigation - Folder structure

1.Angular Routing Application setup steps:

  1. Generate a new Angular project/app with routing option
  2. Generate departmentList and employeeList, and other required components if any
  3. Configure the Routes
  4. Add buttons and use a directive to navigate

1.1. Generate a new Angular project/app with routing option

  • Command to create an Angular app with routing: ng new routing-demo-app --routing

  • Creating a routing module manually in any existing application:

    1. In index.html file under <head> tag add <base href="/"> (It helps application to build/generate/constructs URL/view to load properly)
    2. In the app, folder create app-routing.module.ts file (contains RoutingModule/Routes for application - enter a required path and components details)
    3. import app-routing.module.ts file in app.module.ts file also add in the imports array

1.2. Generate required components if any (departmentList and employeeList, and other)

  • Angular CLI command to generate component: ng g c employee-list -it -is (Inline Template / Inline style)
  • Angular CLI command to generate component: ng g c department-list -it -is and other required components if any

1.3. Configure the Routes

  • In app.component.html add tag/directive: <router-outlet> </router-outlet>
  • In the app-routing.module.ts file, enter required paths and component details to navigate

1.4. Add buttons and use directive to navigate

  • In app.component.html add links/buttons: <a routerLink="/home" routerLinkActive="active">Home</a>
  • We can also use <a routerLink="/home" routerLinkActive="active" routerLinkActiveOptions="{exact:true}">Home</a> to make current exact link active

Syntax & Example: index.html

<!doctype html>
<html lang="en">
<head>
 <meta charset="utf-8">
 <title>AngularRoutingNavigation</title>
 <base href="/">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
 <app-root></app-root>
</body>
</html>

Syntax & Example: app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DepartmentListComponent } from './components/department-list/department-list.component';
import { EmployeeListComponent } from './components/employee-list/employee-list.component';
import { HomeComponent } from './components/home/home.component';
import { ProductListComponent } from './components/product-list/product-list.component';
const routes: Routes = [
 // default path
 // { path: '', component:DepartmentListComponent},
 { path: 'home', component: HomeComponent },
 { path: 'departments', component: DepartmentListComponent },
 { path: 'employees', component: EmployeeListComponent },
 { path: 'products', component: ProductListComponent },
];
@NgModule({
 imports: [RouterModule.forRoot(routes)],
 exports: [RouterModule]
})
export class AppRoutingModule { }
// to store all routing component and avoid importing/writing duplicate list of components in app.routing.module / app.module.
// create an array of all routing components export it, then import it in app.module.ts
export const RoutingComponents = [
 DepartmentListComponent,
 EmployeeListComponent,
 HomeComponent,
 ProductListComponent,
]

Syntax & Example: app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppRoutingModule, RoutingComponents } from './app-routing.module';
import { AppComponent } from './app.component';
// RoutingComponents array - list all the components used in application 
// import { DepartmentContactComponent } from './components/department-contact/department-contact.component';
// import { DepartmentDetailsComponent } from './components/department-details/department-details.component';
// import { DepartmentListComponent } from './components/department-list/department-list.component';
// import { DepartmentOverviewComponent } from './components/department-overview/department-overview.component';
// import { EmployeeListComponent } from './components/employee-list/employee-list.component';
// import { HomeComponent } from './components/home/home.component';
// import { ProductListComponent } from './components/product-list/product-list.component';
// import { WildcardPagenotfoundComponent } from './components/wildcard-pagenotfound/wildcard-pagenotfound.component';
@NgModule({
 declarations: [
 AppComponent,
 RoutingComponents,
 // DepartmentDetailsComponent,
 // DepartmentContactComponent,
 // DepartmentOverviewComponent,
 // DepartmentListComponent,
 // EmployeeListComponent,
 // HomeComponent,
 // ProductListComponent,
 // WildcardPagenotfoundComponent
 ],
 imports: [
 BrowserModule,
 AppRoutingModule
 ],
 providers: [],
 bootstrap: [AppComponent]
})
export class AppModule { }

Syntax & Example: app.component.html

<!--The content below is only a placeholder and can be replaced.-->
<h1 style="text-align:center;">{{ appTitle }}</h1>
<!-- add buttons/links to navigate pages or routings -->
<nav>
 <a routerLink="/home" routerLinkActive="active" routerLinkActiveOptions="{exact:true}">Home</a>
 &nbsp;&nbsp;
 <a routerLink="/departments" routerLinkActive="active" routerLinkActiveOptions="{exact:true}">Departments</a>
 &nbsp;&nbsp;
 <a routerLink="/employees" routerLinkActive="active" routerLinkActiveOptions="{exact:true}">Employees</a>
 &nbsp;&nbsp;
 <a routerLink="/products" routerLinkActive="active" routerLinkActiveOptions="{exact:true}">Products</a> &nbsp;&nbsp;
</nav>
<hr />
<!-- ng new routing-demo-app --routing - defulat include router-outlet in app.component.html. routed views goes here -->
<router-outlet></router-outlet>

Syntax & Example: app.component.ts

import { Component } from '@angular/core';
@Component({
 selector: 'app-root',
 templateUrl: './app.component.html',
 styleUrls: ['./app.component.css']
})
export class AppComponent {
 public appTitle = 'Angular Routing and Navigation Module';
}

Syntax & Example: styles.css

/* You can add global styles to this file, and also import other style files */
/* common global generic styles */
.custom-divider {
 margin: 30px 0px;
 border-bottom:2px dashed gray;
}
h1,h2,h3 {
 text-transform: uppercase;
 /* text-transform: capitalize; */
}
h2 {
 text-decoration: underline;
}
body {
 font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
 letter-spacing: 2px;
}
li {
 margin: 10px 0px;
}
input {
 padding: 5px;
}
button {
 border-radius: 5px;
 padding: 10px 15px;
 background-color: teal;
 border: none;
 outline: none;
 cursor: pointer;
 color: lightcyan;
}
.button-sub {
 background-color: rgba(0, 128, 128, 0.6);
 color: white;
}
/* route and navigation - links */
nav a {
 padding:10px;
 text-decoration: none;
 margin-top: 10px;
 display: inline-block;
 background-color: #eeeeee;
 border-radius: 4px;
}
nav a:visited, a:link, a {
 color:#607D8B;
}
nav a:hover {
 color:#039be5;
 background-color: #CFD8DC;
}
nav a.active {
 color:#039be5;
 font-weight: bold;
 text-decoration: underline;
}
/* route and navigation - list badge */
.items {
}
.items li, .link-sub {
 width: 200px;
 cursor: pointer;
 width: 150px;
 padding: 10px;
 text-decoration: none;
 margin-top: 10px;
 background-color: #eeeeee;
 border-radius: 4px;
}
.badge {
 background: teal;
 padding: 10px;
 margin-right: 5px;
 position: relative;
 left: -10px;
 border-radius: 4px 0px 0px 4px;
}
.description {
}
/* optional parameter - show highlighted */
.items li.selected {
 color:#039be5;
 background-color: #CFD8DC;
}

2 Wildcard Route and Redirecting Routes (Dealing with unavailable-non-configured route [Page not found])

  • User can type/enter any unavailable-non-configured route/URL and can get many erros in console, like http://localhost:5000/try Error: (Cannot match any routes, URL segment 'try'...)
  • To deal/handle any unwanted path or unavailable routes we must need to create a new component named page not found component OR 404 component and add 'wildcard **' route
  • Wildcard ** routes or any paths with parameters (employees/1 or routes/parameters) must come last in app-routing.module.ts router configuration as router tries to match the paths from top to bottom
  • In app-routing.module.ts route must be configured in order: most specific at the tpo to list important/specific at the bottom
  • Default Route: While using wildcard ** routes we also need to provide default route like '{ path: '', component:DepartmentListComponent}' OR '{ path: '', redirectTo:'departments', pathMatch:'full'}'

Steps:

  • Create a new component for page not found: ng g c wildcard-pagenotfound with a instructional markup: 404 page not found!
  • In app-routing.module.ts at the bottom/last add a new wildcard route: { path: '**', component: WildcardPagenotfoundComponent }

Syntax & Example: wildcard-pagenotfound.component.html

<p>
 404 page not found! <br/>
 Path/URL not available!! <br/>
 <strong>Try Again!!!</strong> 
</p>

Syntax & Example: app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DepartmentListComponent } from './components/department-list/department-list.component';
import { EmployeeListComponent } from './components/employee-list/employee-list.component';
import { HomeComponent } from './components/home/home.component';
import { ProductListComponent } from './components/product-list/product-list.component';
import { WildcardPagenotfoundComponent } from './components/wildcard-pagenotfound/wildcard-pagenotfound.component';
const routes: Routes = [
 // default path
 // { path: '', component:DepartmentListComponent},
 { path: 'home', component: HomeComponent },
 { path: '', redirectTo: 'home', pathMatch: 'full' },
 { path: 'departments', component: DepartmentListComponent },
 { path: 'employees', component: EmployeeListComponent },
 { path: 'products', component: ProductListComponent },
 { path: '**', component: WildcardPagenotfoundComponent }
];
@NgModule({
 imports: [RouterModule.forRoot(routes)],
 exports: [RouterModule]
})
export class AppRoutingModule { }
// to store all routing component and avoid importing/writing duplicate list of components in app.routing.module / app.module.
// create an array of all routing components export it then imports it in app.module.ts
export const RoutingComponents = [
 DepartmentListComponent,
 EmployeeListComponent,
 HomeComponent,
 ProductListComponent,
 WildcardPagenotfoundComponent,
]

Image - Output - wildcard-route / Page not found!

Image - Output - wildcard-route / Page not found!

Image - Output - wildcard-route / Page not found!

Image - Output - wildcard-route / Page not found!

3 Route Parameters

  1. In app-routing.module.ts create departments/:id path route parameters for items under department list component
  2. In department-list.component.ts class file create a array of departments object
  3. In department-list.component.html view file iterate/*ngFor through departments array and pass departments id as a route parameter
    • on click of the department list item, it will take to department-details.component page with selected department id, at the same time browser location path will be displayed as localhost:5000/department:2 (selected department id )
    • To navigate from code/links/buttons we need router service as a dependency
  4. Create and use a new component to show details: department-details.component.ts - read the departments id passed as a parameter and show the route view accordingly
    • activatedRoute.snapshot.paramMap.get() is used to read the routes/parameters passed

Syntax & Example: department-list.component.ts

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
@Component({
 selector: 'app-department-list',
 templateUrl: './department-list.component.html',
 styleUrls: ['./department-list.component.css']
})
export class DepartmentListComponent implements OnInit {
 public departments = [
 { 'id': 1, 'name': 'JavaScript' },
 { 'id': 2, 'name': 'Angular' },
 { 'id': 3, 'name': 'NodeJS' },
 { 'id': 4, 'name': 'ReactJS' },
 { 'id': 5, 'name': 'VueJs' },
 ]
 
 constructor(private router: Router) { }
 ngOnInit() {
 }
 onLinkSelect(curDepartment) {
 console.log('onLinkSelect curDepartment');
 // navigate ( path, route parameter)
 this.router.navigate(['departments', curDepartment.id]);
 }
}

Syntax & Example: department-list.component.html

<div>
 <h3>Department list:</h3>
 <ul class="items">
 Click on department to see more details:
 <!-- on link click call function/method to navigate -->
 <li *ngFor="let department of departments" (click)="onLinkSelect(department)">
 <span class="badge">{{department.id}}</span>
 <span class="description">{{department.name}}</span>
 </li>
 </ul>
</div>

Syntax & Example: app-routing.module

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DepartmentDetailsComponent } from './components/department-details/department-details.component';
import { DepartmentListComponent } from './components/department-list/department-list.component';
import { EmployeeListComponent } from './components/employee-list/employee-list.component';
import { HomeComponent } from './components/home/home.component';
import { ProductListComponent } from './components/product-list/product-list.component';
import { WildcardPagenotfoundComponent } from './components/wildcard-pagenotfound/wildcard-pagenotfound.component';
const routes: Routes = [
 // default path
 // { path: '', component:DepartmentListComponent},
 { path: 'home', component: HomeComponent },
 { path: '', redirectTo: 'home', pathMatch: 'full' },
 { path: 'departments', component: DepartmentListComponent },
 { path: 'departments/:id', component: DepartmentDetailsComponent },
 { path: 'employees', component: EmployeeListComponent },
 { path: 'products', component: ProductListComponent },
 { path: '**', component: WildcardPagenotfoundComponent }
];
@NgModule({
 imports: [RouterModule.forRoot(routes)],
 exports: [RouterModule]
})
export class AppRoutingModule { }
// to store all routing component and avoid importing/writing duplicate list of components in app.routing.module / app.module.
// create an array of all routing components export it then imports it in app.module.ts
export const RoutingComponents = [
 DepartmentDetailsComponent,
 DepartmentListComponent,
 EmployeeListComponent,
 HomeComponent,
 ProductListComponent,
 WildcardPagenotfoundComponent,
]

Syntax & Example: department-details.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
 selector: 'app-department-details',
 templateUrl: './department-details.component.html',
 styleUrls: ['./department-details.component.css']
})
export class DepartmentDetailsComponent implements OnInit {
 // to hold the currently passed id parameter
 public selectedDepartmentId;
 constructor(private activatedRoute: ActivatedRoute) { }
 ngOnInit() {
 // read the route parameter
 // snapshot approach 
 console.log(this.activatedRoute.snapshot.paramMap);
 let routeParamId = parseInt(this.activatedRoute.snapshot.paramMap.get('id'));
 this.selectedDepartmentId = routeParamId;
 }
}

Syntax & Example: department-details.component.html

<h3>Selected Deparment Details ID : {{ selectedDepartmentId }} </h3>

Image - Output - Route Parameters Department List

Image - Output - Route Parameters Department List

Image - Output - Route Parameters Department Clicked/Selected

Image - Output - Route Parameters Department Clicked/Selected

4 paramMap Observable

  • Using the activatedRoute.snapshot got some drawback like: when will navigate back next / previous next from child component (details component to list component) snapshot approach does not work
    1. In department-details.component.html add links Previous & Next to see rest of departments with click handler <a (click)="goPrevious()">Back </a>
    2. In department-details.component.ts create a handler goPrevious() & goNext() with required logic
    3. If you will observe the drawback here is on Previous & Next button clicks, only url updates/changing but view/template not changing (ngOnInit does not get call)
    4. To overcome activatedRoute.snapshot problems will use paramMap Observable with subscribe

Syntax & Example: department-details.component.html

<h3>Selected Deparment Details ID : {{ selectedDepartmentId }} </h3>
<br />
<a (click)="goPrevious()" class="link-sub">Previous</a> &nbsp; &nbsp;
<a (click)="goNext()" class="link-sub">Next</a>

Syntax & Example: department-details.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
@Component({
 selector: 'app-department-details',
 templateUrl: './department-details.component.html',
 styleUrls: ['./department-details.component.css']
})
export class DepartmentDetailsComponent implements OnInit {
 // to hold the currently passed id parameter
 public selectedDepartmentId;
 constructor(private activatedRoute: ActivatedRoute, private router: Router) { }
 ngOnInit() {
 // read the route parameter
 // snapshot approach 
 // console.log(this.activatedRoute.snapshot.paramMap);
 // let routeParamId = parseInt(this.activatedRoute.snapshot.paramMap.get('id'));
 // this.selectedDepartmentId = routeParamId;
 // paramMap Observable approach 
 this.activatedRoute.paramMap.subscribe((params: ParamMap) => {
 let id = parseInt(params.get('id')); // let id = Number(params.get('id'))
 this.selectedDepartmentId = id;
 })
 }
 goPrevious() {
 let previousId = this.selectedDepartmentId - 1;
 this.router.navigate(['/departments', previousId]);
 }
 goNext() {
 let nextId = this.selectedDepartmentId + 1;
 this.router.navigate(['/departments', nextId]);
 }
}

Image - Output - Route Parameters Previous ID

Image - Output - Route Parameters Previous ID

Image - Output - Route Parameters Next ID

Image - Output - Route Parameters Next ID

Image - Output - Route Parameters Observables Next ID

Image - Output - Route Parameters Observables Next ID

5 Optional Route Parameters

  • By using Back button in department-details.component.html we must navigate back to department-list.component.html and show clicked department in selected state`
    1. In department-details.component add Back button: <button click="goToDepartments()">Back </button>
    2. In department-details.component.ts create a handler goToDepartments() with required logic, // Use Back button to go to main list page and highlight the link by passing optional parameters with departments details, when back it shows in url http://localhost:5000/departments;id=4
    3. In department-list.component.ts add required login in ngOnInit() life cycle hook to read the passed optional parameter and to highlight clicked department button

Syntax & Example: department-details.component.html

<!-- // back button - method to handle optional parameters and show current clicked department highlighted -->
<button (click)="goToDepartments()" class="button-sub">Back</button>

Syntax & Example: department-details.component.ts

// back button - method to handle optional parameters and show current department highlighted
goToDepartments() {
 console.log('goToDepartments clicked');
 let currentSelectedId = this.selectedDepartmentId ? this.selectedDepartmentId : null
 //sending optional parameter - used for some logic
 //this.router.navigate(["/departments", { id: currentSelectedId, test: 'test-param-value' }])
 // relative path, links parameter array - {key:value}, {relativeTo property}
 // we can pass multiple parameters as per our requirements
 // this.router.navigate(['../', { id: currentSelectedId, name: 'Hello' }]);
 this.router.navigate(['../', { id: currentSelectedId }]);
}

Syntax & Example: department-list.component.ts

ngOnInit() {
 this.activatedRoute.paramMap.subscribe((params: ParamMap) => {
 let id = parseInt(params.get('id')); // let id = Number(params.get('id'))
 this.selectedDepartmentId = id;
 })
}
/* on department click */
onLinkSelect(curDepartment) {
 console.log('onLinkSelect curDepartment');
 // navigate ( path, route parameter)
 // this.router.navigate(['departments', curDepartment.id]);
 // relative path, links parameter array, relativeTo property
 this.router.navigate([curDepartment.id]);
}
// to compare/match current route clicked and optional parameter
isSelectedRouteMatchOptionalParam(curDepartment) {
 return curDepartment.id === this.selectedDepartmentId;
}

Syntax & Example: styles.css

/* optional parameter - show highlighted */
.items li.selected {
 color:#039be5;
 background-color: #CFD8DC;
}

Image - Output - Optional Route Parameters Back

Image - Output - Optional Route Parameters Back

Image - Output - Optional Route Parameters Selected List

Image - Output - Optional Route Parameters Selected List

6 Relative Navigation

  • Absolute path starts with forward slash / (paths like /name are absolute/fixed path)
  • Absolute/Fixed paths are not flexible as if file/route name changes we need to make change at all occurrences/places in an application
  • Its advisable to use relative path/navigation with relativeTo property

Syntax & Example: department-list.component.ts

/* on department click */
onLinkSelect(curDepartment) {
 console.log('onLinkSelect curDepartment');
 // navigate ( path, route parameter)
 // this.router.navigate(['departments', curDepartment.id]);
 // relative path, links parameter array, relativeTo property
 this.router.navigate([curDepartment.id], { relativeTo: this.activatedRoute }); // to the current route append the department id and navigate to that URL
}

Syntax & Example: department-details.component.ts

// back button - method to handle optional parameters and show current department highlighted
goToDepartments() {
 console.log('goToDepartments clicked');
 let currentSelectedId = this.selectedDepartmentId ? this.selectedDepartmentId : null
 //sending optional parameter - used for some logic
 //this.router.navigate(["/departments", { id: currentSelectedId, test: 'test-param-value' }])
 // relative path, links parameter array - {key:value}, {relativeTo property}
 // we can pass multiple parameters as per our requirements
 // this.router.navigate(['../', { id: currentSelectedId, name: 'Hello' }]);
 this.router.navigate(['../', { id: currentSelectedId }], { relativeTo: this.activatedRoute }); // to the current route append the department id and navigate to that URL
}

7 Child Routes

  • In application, some routes/path/links/pages viewed only within other routes - in such scenario we can create and use child routes in app-routing.module.ts
  • Like inside department-details component we need to show links/pages like: Overview, Contact, Pictures etc.
  • Create child components with angular cli command:
    • department-overview - ng g c department-overview
    • department-contact - ng g c department-contact
  • Change/add app-routing.module.ts with children property
  • Inside parent component department-details create <router-outlet> as a container area for loading pages, also create buttons overview and contact to navigate to component/pages/route <button (click)="showOverview()">Overview</button>

Syntax & Example: app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { DepartmentContactComponent } from './components/department-contact/department-contact.component';
import { DepartmentDetailsComponent } from './components/department-details/department-details.component';
import { DepartmentListComponent } from './components/department-list/department-list.component';
import { DepartmentOverviewComponent } from './components/department-overview/department-overview.component';
import { EmployeeListComponent } from './components/employee-list/employee-list.component';
import { HomeComponent } from './components/home/home.component';
import { ProductListComponent } from './components/product-list/product-list.component';
import { WildcardPagenotfoundComponent } from './components/wildcard-pagenotfound/wildcard-pagenotfound.component';
const routes: Routes = [
 // default path
 // { path: '', component:DepartmentListComponent},
 { path: 'home', component: HomeComponent },
 { path: '', redirectTo: 'home', pathMatch: 'full' },
 { path: 'departments', component: DepartmentListComponent },
 {
 path: 'departments/:id', component: DepartmentDetailsComponent,
 children: [
 { path: 'overview', component: DepartmentOverviewComponent },
 { path: 'contact', component: DepartmentContactComponent },
 ]
 },
 { path: 'employees', component: EmployeeListComponent },
 { path: 'products', component: ProductListComponent },
 { path: '**', component: WildcardPagenotfoundComponent }
];
@NgModule({
 imports: [RouterModule.forRoot(routes)],
 exports: [RouterModule]
})
export class AppRoutingModule { }
// to store all routing component and avoid importing/writing duplicate list of components in app.routing.module / app.module.
// create an array of all routing components export it then import it in app.module.ts
export const RoutingComponents = [
 DepartmentContactComponent,
 DepartmentDetailsComponent,
 DepartmentListComponent,
 DepartmentOverviewComponent,
 EmployeeListComponent,
 HomeComponent,
 ProductListComponent,
 WildcardPagenotfoundComponent,
]

Syntax & Example: department-details.component.html

<h3>Selected Deparment Details ID : {{ selectedDepartmentId }} </h3>
<br />
<a (click)="goPrevious()" class="link-sub">Previous</a> &nbsp; &nbsp;
<a (click)="goNext()" class="link-sub">Next</a>
<button (click)="showOverview()">Overview </button> &nbsp; &nbsp;
<button (click)="showContact()">Contact</button>
<router-outlet></router-outlet>
<br /> <br />
<hr />
<br />
<!-- // back button - method to handle optional parameters and show current clicked department highlighted -->
<button (click)="goToDepartments()" class="button-sub">Back</button>

Syntax & Example: department-details.component.ts

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, ParamMap } from '@angular/router';
@Component({
 selector: 'app-department-details',
 templateUrl: './department-details.component.html',
 styleUrls: ['./department-details.component.css']
})
export class DepartmentDetailsComponent implements OnInit {
 
 // to hold the currently passed id parameter
 public selectedDepartmentId;
 constructor(private activatedRoute: ActivatedRoute, private router: Router) { }
 ngOnInit() {
 // read the route parameter
 // snapshot approach 
 // console.log(this.activatedRoute.snapshot.paramMap);
 // let routeParamId = parseInt(this.activatedRoute.snapshot.paramMap.get('id'));
 // this.selectedDepartmentId = routeParamId;
 // paramMap Observable approach 
 this.activatedRoute.paramMap.subscribe((params: ParamMap) => {
 let id = parseInt(params.get('id')); // let id = Number(params.get('id'))
 this.selectedDepartmentId = id;
 })
 }
 /* Previous/Back button click */
 goPrevious() {
 let previousId = this.selectedDepartmentId - 1;
 this.router.navigate(['/departments', previousId]);
 }
 /* Next button click */
 goNext() {
 let nextId = this.selectedDepartmentId + 1;
 this.router.navigate(['/departments', nextId]);
 }
 // back button - method to handle optional parameters and show current department highlighted
 goToDepartments() {
 console.log('goToDepartments clicked');
 let currentSelectedId = this.selectedDepartmentId ? this.selectedDepartmentId : null
 //sending optional parameter - used for some logic
 //this.router.navigate(["/departments", { id: currentSelectedId, test: 'test-param-value' }])
 // relative path, links parameter array - {key:value}, {relativeTo property}
 // we can pass multiple parameters as per our requirements
 // this.router.navigate(['../', { id: currentSelectedId, name: 'Hello' }]);
 this.router.navigate(['../', { id: currentSelectedId }], { relativeTo: this.activatedRoute }); // to the current route append the department id and navigate to that URL
 }
 /* on overview button click */
 showOverview() {
 this.router.navigate(['overview'], { relativeTo: this.activatedRoute })
 }
 /* on contact button click */
 showContact() {
 this.router.navigate(['contact'], { relativeTo: this.activatedRoute })
 }
}

Image - Output - Department List

Image - Output - Department List

Image - Output - Child Route Department Overview

Image - Output - Child Route Department Overview

Image - Output - Child Route Department Contact

Image - Output - Child Route Department Contact

Image - Output - Optional Route Parameter Show Selected Department highlighted

Image - Output - Optional Route Parameter Show Selected Department highlighted

AltStyle によって変換されたページ (->オリジナル) /