Routing is the mechanism by which requests(as specified by a URL and HTTP method) are routed to the code that handles them.
- Without page reload
- The angular router is an essential element of the angular platform.
- It allows developers to build single page applications with multiple states and views using routes and components and allows client side navigation and routing between the various components.
- It's built and maintained by the core team behind developement and it's contained in the
@angular/router
package. - If you want to navigate to different pages in your application, but you also want the application to be a SPA(single Page Application), with no page reloading then you can use Angular Router.
Features in Angular Router:
- The components, routes and paths
- The router outlet
- The route matching strategies
- Route parameters
- Query parameters
- Route guards
- Route resolvers
- The RouterLink directive (replaces the href attribute)
- Auxiliary routes
- Primary and secondary router outlets
1.How to configure routes
Step 1: Create project, when asking for routing say yes.
ng new routing-demo
Make sure in package.json it is added:
How to add routing to an existing project:
ng generate module app-routing --flat --module=app
lets add component:
ng g c home
ng g c about
ng g c contact
Add paths in routing file:
const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
];
In app.component.html file:
<h1>Routing app demo</h1>
<router-outlet></router-outlet>
<router-outlet>
: It is a directive exported b RouterModule and acts as a placeholder that indicates to the router where it needs to insert the matched components.
You will see when we route to a specific path instead of we can see the components are rendering.
Lets create links In app.component.html file
:
<h1>Routing app demo</h1>
<a routerLink="home">Home</a>
<a routerLink="about">About</a>
<a routerLink="contact">Contact</a>
<router-outlet></router-outlet>
When we click on links the components will render.
Here I have clicked on home link that's why the home component rendered.
2.Page Not Found | Wildcards | pathMatch
Let's try to route which is not added in our routes:
There will be error because we haven't configure this path in our routing file.
Now, let's add path when user wanted to navigate which is not in our scope:
For that lets add one component:
ng g c page-not-found
Let's add path for that:
const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{path: '**', component: PageNotFoundComponent}
];
Wildcards: path: '**' is called wildcard entry.
Let's configure path for empty path:
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{path: '**', component: PageNotFoundComponent}
];
If user enters nothing then that navigates to HomeComponent
.
If I navigate to http://localhost:4200
it will automatically redirect to http://localhost:4200/home
3.Route parameters or Dynamic Routing
Let's create 2 components
ng g c employees-list
ng g c employees-details
Let's add path for employee-list in app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{ path: 'employee', component: EmployeesListComponent},
{path: '**', component: PageNotFoundComponent}
];
And will add link for the same in app.component.html
<h1>Routing app demo</h1>
<a routerLink="home">Home</a> <br>
<a routerLink="about">About</a> <br>
<a routerLink="contact">Contact</a> <br>
<a routerLink="employee">Employees</a> <br>
<router-outlet></router-outlet>
Lets add create array of Employee in list
export class EmployeesListComponent implements OnInit {
Employees = [
{"id": 1 , "name": 'John'},
{"id": 2 , "name": 'smith'},
{"id": 3 , "name": 'kumar'},
{"id": 4 , "name": 'ram'},
{"id": 5 , "name": 'Ramesh'}
]
}
To show list of employees on html
<h1>Employees List</h1>
<ul>
<li (click) = "EmpClick(emp)"
*ngFor="let emp of Employees">
{{emp.id}} - {{emp.name}}
</li>
</ul>
Lets fetch with employee ID
app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{ path: 'employee', component: EmployeesListComponent},
{ path: 'employee/:id', component: EmployeesListComponent},
{path: '**', component: PageNotFoundComponent}
];
Employee-list.component.html
<h1>Employees List</h1>
<ul class="list-group">
<li (click) = "EmpClick(emp)"
class="list-group-item bg-dark text-white"
*ngFor="let emp of Employees">
{{emp.id}} - {{emp.name}}
</li>
</ul>
Employee-list.component.ts
import { Router } from '@angular/router';
export class EmployeesListComponent implements OnInit {
Employees = [
{"id": 1 , "name": 'John'},
{"id": 2 , "name": 'smith'},
{"id": 3 , "name": 'kumar'},
{"id": 4 , "name": 'ram'},
{"id": 5 , "name": 'Ramesh'}
]
constructor(private router: Router) {
}
EmpClick(emp: any){
this.router.navigate(['/employee', emp.id])
}
}
Added some bootstrap for better representation
Observe the link, when I click on 4th employee it routes to
http://localhost:4200/employee/4
Now lets navigate user to the employee details:
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'contact', component: ContactComponent },
{ path: 'employee', component: EmployeesListComponent},
{ path: 'employee/:id', component: EmployeesDetailsComponent},
{path: '**', component: PageNotFoundComponent}
];
Employee-details.component.ts
import { ActivatedRoute } from '@angular/router';
export class EmployeesDetailsComponent implements OnInit {
public EMPID: any;
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit(): void {
let id = this.activatedRoute.snapshot.paramMap.get('id');
this.EMPID = id;
}
}
Employee-details.component.ts
<h2>
You have selected Employee with id {{EMPID}}
</h2>
Now when you select any employee you will route to employee-details component.
4.Multiple route parameters
{ path: 'employee/:id/:name', component: EmployeesDetailsComponent},
employee-list.component.ts
EmpClick(emp: any){
this.router.navigate(['/employee', emp.id, emp.name]);
}
employee-details.details.ts
export class EmployeesDetailsComponent implements OnInit {
public EMPID: any;
public EMPNAME: any;
constructor(private activatedRoute: ActivatedRoute) { }
ngOnInit(): void {
let id = this.activatedRoute.snapshot.paramMap.get('id');
this.EMPID = id;
let name = this.activatedRoute.snapshot.paramMap.get('name');
this.EMPNAME = name;
}
}
employee-details.component.html
<h2>
You have selected Employee with id {{EMPID}}
You have selected Employee with name {{EMPNAME}}
</h2>
5.Absolute and Relative path
Example of Relative path:
The relative path is concatenated with current path that till now we have seen
In this example, if you see I want to go Home and then About and again home. This is the wrong path http://localhost:4200/about/home
When I am redirecting to Home when I am in About page the correct path should be http://localhost:4200/home
Let's add link of home page in the about page:
About.component.
ts
<a routerLink="home">Home</a> <br>
And When I click on Home link, observe we redirect to page not found
To resolve this we will use Absolute path.
we will just add / before home link:
About.component.
ts
<a routerLink="home">Home</a> <br>
Now it will successfully redirect from About to home link:
For one step back you can also do this:
About.component.
ts
<a routerLink="../">Home</a> <br>
6.paramMap observable
Let's add previous
and next
button on employee-details.component.ts
import { ActivatedRoute, Router } from '@angular/router';
export class EmployeesDetailsComponent implements OnInit {
public EMPID: any;
constructor(private activatedRoute: ActivatedRoute, private route: Router) { }
ngOnInit(): void {
let id = this.activatedRoute.snapshot.paramMap.get('id');
this.EMPID = id;
}
previous(){
let previousId= parseInt(this.EMPID) - 1;
this.route.navigate(['/employee', previousId]);
}
next(){
let nextId = parseInt(this.EMPID) + 1;
this.route.navigate(['/employee', nextId]);
}
}
employee-details.component.html
<h2>
You have selected Employee with id {{EMPID}}
</h2>
<button (click) = "previous()">Previous</button>
<button (click) = "next()">Next</button>
employee-list.component.ts
EmpClick(emp: any){
this.router.navigate(['/employee', emp.id]);
}
If you observe here our view is not updated when I click on next button, this is the drawback of snapshot approach.
We will see how we can resolve this with help of paramMap
observable
- *ParamMap * is the method of ActivatedRoute and it will return an
- observable and it will give data only if we subscribe to it
- The argument in the subscribe method is an arrow function.
- The observable provides the parameter which we strongly typed to paramMap.
- paramMap is coming from Router package.
employee-details.component.ts
ngOnInit(): void {
// let id = this.activatedRoute.snapshot.paramMap.get('id');
// this.EMPID = id;
this.activatedRoute.paramMap.subscribe((params: ParamMap) => {
let id = params.get('id');
this.EMPID = id;
});
}
Observe here what id is in params is displayed on the view:
7.Optional Route Parameters
In Angular, route parameters allow you to pass values to a route, which can then be used by the associated component to display or process specific data. While some parameters are mandatory, others can be optional, providing flexibility in designing dynamic and user-friendly routes.
This guide explains optional route parameters, how to define them, and how to use them in Angular applications.
What Are Optional Route Parameters?
Optional route parameters are parameters that are not required to navigate to a route. If omitted, the route still works without error, making it possible to build more versatile URLs.
For example:
- URL with parameter:
/profile/123
- URL without parameter:
/profile
Both can point to the same component, but with different behavior based on whether the parameter is present.
Defining Optional Route Parameters
In Angular, optional parameters are typically defined using the query parameters or a route path configuration.
1. Using Query Parameters
Query parameters are the most common way to handle optional parameters.
Route Configuration
Define a route without hardcoding the parameter in the path:
const routes: Routes = [
{ path: 'profile', component: ProfileComponent }
];
Navigating with Query Parameters
You can pass query parameters programmatically:
this.router.navigate(['/profile'], { queryParams: { id: 123 } });
Accessing Query Parameters in a Component
Use the ActivatedRoute
service to retrieve query parameters:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-profile',
template: `<p>User ID: {{ userId }}</p>`
})
export class ProfileComponent implements OnInit {
userId: string | null = null;
constructor(private route: ActivatedRoute) {}
ngOnInit(): void {
this.route.queryParams.subscribe(params => {
this.userId = params['id'] || 'No ID provided';
});
}
}
2. Using Optional Parameters in Path
You can include optional parameters in the route path using parameterized segments.
Route Configuration
Define a route with optional parameters using a wildcard approach:
const routes: Routes = [
{ path: 'profile/:id', component: ProfileComponent },
{ path: 'profile', component: ProfileComponent }
];
Here, the id
parameter is optional because the route is defined both with and without the parameter.
Navigating with Optional Parameters
Use navigate
or direct links:
// With parameter
this.router.navigate(['/profile', 123]);
// Without parameter
this.router.navigate(['/profile']);
Accessing Parameters in a Component
Use ActivatedRoute
to access parameters:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-profile',
template: `<p>User ID: {{ userId }}</p>`
})
export class ProfileComponent implements OnInit {
userId: string | null = null;
constructor(private route: ActivatedRoute) {}
ngOnInit(): void {
this.route.params.subscribe(params => {
this.userId = params['id'] || 'No ID provided';
});
}
}
Combining Query Parameters and Optional Path Parameters
You can use both query parameters and optional path parameters in the same route for maximum flexibility:
const routes: Routes = [
{ path: 'profile/:id', component: ProfileComponent }
];
Navigate with:
this.router.navigate(['/profile', 123], { queryParams: { name: 'John' } });
Access in the component:
ngOnInit(): void {
this.route.params.subscribe(params => {
this.userId = params['id'];
});
this.route.queryParams.subscribe(params => {
this.userName = params['name'];
});
}
Best Practices
-
Use Query Parameters for Truly Optional Data
- Ideal for filters, sorts, and non-mandatory identifiers.
-
Provide Default Values
- Fallback to defaults when optional parameters are not provided.
-
Avoid Overuse of Parameters
- Too many optional parameters can complicate route management.
-
Document Your Routes
- Clearly indicate which parameters are optional to avoid confusion.
Conclusion
Optional route parameters offer flexibility in designing Angular routes, enabling more dynamic navigation experiences. By using query parameters or optional path parameters, you can tailor the behavior of your application to meet diverse user needs. Mastering these techniques is essential for building scalable and user-friendly Angular applications.
8.Child Routes or Nested Routes
Product is Parent and T-shirts and Trousers components are child:
Lets create 3 component:
ng g c products
ng g c tshirts
ng g c trousers
In app-routing.module.ts
{ path: 'products', component: ProductsComponent },
In app.component.html
<a routerLink="products">Products</a> <br>
Now, let's configure the child components:
In app-routing.module.ts
{
path: 'products',
component: ProductsComponent,
children: [
{path: 'tshirts', component: TshirtsComponent},
{path: 'trousers', component: TrousersComponent}
]
},
product.somponent.html
<h2>All products are here...</h2>
<a routerLink="tshirts">T-Shirts</a>
<a routerLink="trousers">Trousers</a>
<router-outlet></router-outlet>
9.Adding All The Routes Inside Bootstrap Navbar
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" routerLink="home">Home </a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="products" >Products</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="about" >About</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="contact" >Contact</a>
</li>
<li class="nav-item">
<a class="nav-link" routerLink="employee" >Employee</a>
</li>
</ul>
</div>
</nav>
<h1>Routing app demo</h1>
<router-outlet></router-outlet>
10.Auxiliary Routes OR Named Routes & Multiple Router Outlets
- Angular supports the concept of auxiliary routes, which allow you to set up and navigate multiple independent routes in a single app.
- Auxiliary routes allow the user to access or toggle portions of the page, such as a side-bar or dialog, using the URL.
- Each component has one primary route and zero or more auxiliary outlets.
- Auxiliary outlets must have unique name within a component.
- To define the auxiliary route we must first add a named router outlet where contents for the auxiliary route are to be rendered.
let's create 2 components:
ng g c courses
ng g c courses-details
app-souting.module.ts
{ path: 'courses', component: CoursesComponent },
{
path: 'coursedetails',
outlet: 'course_details',
component: CoursesDetailsComponent
},
app.component.html
<li class="nav-item">
<a class="nav-link" routerLink="courses" >Courses</a>
</li>
<li class="nav-item">
<a class="nav-link" [routerLink]="[{outlet: {course_details: ['coursedetails'] }}]" >Courses Details</a>
</li>
<router-outlet></router-outlet>
<router-outlet name="course_details"></router-outlet>
Output:
You can see these blogs to cover all angular concepts:
Beginner's Roadmap: Your Guide to Starting with Angular
- Core Angular Concepts
- Services and Dependency Injection
- Routing and Navigation
- Forms in Angular
- RxJS and Observables
- State Management
- Performance Optimization
HAPPY CODING!
Top comments (1)
Hi Renuka Patil,
Very nice and helpful !
Thanks for sharing.