Routing is a critical feature in Angular applications, enabling navigation between different views or components. Angular Router provides a robust framework for managing navigation, URL management, and route guards. In this guide, we will go through the complete process of setting up Angular Router, understanding routes, and implementing advanced routing features in your Angular application.
Introduction to Angular Router
Angular Router is a library that allows developers to implement client-side routing in single-page applications (SPAs). Instead of loading a new HTML page for each view, Angular Router dynamically updates the view based on the URL, making navigation faster and smoother.
The router provides the following features:
- Mapping URLs to components.
- Nested routes and child routes.
- Route guards for authentication and authorization.
- Lazy loading of modules for performance optimization.
- Route parameters and query parameters handling.
- Programmatic navigation and URL redirection.
Understanding and implementing Angular Router is essential for building scalable and maintainable Angular applications.
Prerequisites
Before we begin, ensure you have the following:
- Node.js installed (version 14 or above recommended).
- Angular CLI installed globally (
npm install -g @angular/cli
). - Basic knowledge of Angular components and modules.
You can verify your Angular CLI installation by running:
ng version
This command will display the installed Angular version and CLI version.
Step 1: Create a New Angular Project
If you do not have an existing Angular project, you can create one using Angular CLI:
ng new angular-routing-app
cd angular-routing-app
ng serve
This will create a new Angular application named angular-routing-app
and serve it at http://localhost:4200
.
Step 2: Understanding Angular Modules
Angular applications are modular. Each module encapsulates a set of components, directives, and services. The main module is AppModule
, located in src/app/app.module.ts
.
Here is a basic structure of AppModule
:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
To enable routing, we need to import RouterModule
and define routes.
Step 3: Import RouterModule in AppModule
First, import RouterModule
and Routes
from @angular/router
:
import { RouterModule, Routes } from '@angular/router';
Next, define a Routes
array. Each route maps a URL path to a component:
import { HomeComponent } from './home/home.component';
import { AboutComponent } from './about/about.component';
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent }
];
Finally, include RouterModule.forRoot(routes)
in the imports
array of your module:
@NgModule({
declarations: [
AppComponent,
HomeComponent,
AboutComponent
],
imports: [
BrowserModule,
RouterModule.forRoot(routes)
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
At this point, Angular Router is configured in your application.
Step 4: Creating Components for Routes
You need components to associate with routes. Generate components using Angular CLI:
ng generate component home
ng generate component about
This will create home
and about
components along with their HTML and CSS files.
HomeComponent (home.component.ts
)
import { Component } from '@angular/core';
@Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent { }
AboutComponent (about.component.ts
)
import { Component } from '@angular/core';
@Component({
selector: 'app-about',
templateUrl: './about.component.html',
styleUrls: ['./about.component.css']
})
export class AboutComponent { }
Step 5: Adding RouterOutlet
<router-outlet>
is a placeholder in your template where routed components will be displayed.
Edit app.component.html
:
<nav>
<a routerLink="">Home</a>
<a routerLink="about">About</a>
</nav>
<router-outlet></router-outlet>
Now, when you navigate to /
or /about
, the corresponding component will render inside <router-outlet>
.
Step 6: Navigating Using RouterLink
Angular provides the routerLink
directive for navigation. It binds an HTML element to a route.
Example in app.component.html
:
<nav>
<a routerLink="" routerLinkActive="active">Home</a>
<a routerLink="about" routerLinkActive="active">About</a>
</nav>
routerLink
specifies the route path.routerLinkActive
adds a CSS class when the route is active.
Step 7: Using Route Parameters
Sometimes, you need dynamic routes with parameters. Example: /user/:id
.
Add a route with a parameter:
{ path: 'user/:id', component: UserComponent }
Generate UserComponent
:
ng generate component user
Access the parameter in the component using ActivatedRoute
:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
@Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
userId: string = '';
constructor(private route: ActivatedRoute) { }
ngOnInit(): void {
this.userId = this.route.snapshot.paramMap.get('id')!;
}
}
Navigate programmatically:
import { Router } from '@angular/router';
constructor(private router: Router) { }
goToUser(id: number) {
this.router.navigate(['/user', id]);
}
Step 8: Nested or Child Routes
Angular Router supports nested routes for hierarchical navigation.
Define child routes:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'products', component: ProductsComponent, children: [
{ path: 'electronics', component: ElectronicsComponent },
{ path: 'clothing', component: ClothingComponent }
]}
];
Add <router-outlet>
in ProductsComponent
template to display child components.
Step 9: Redirects and Wildcard Routes
Redirects help guide users to specific routes:
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
pathMatch: 'full'
ensures exact match for redirect.**
wildcard handles 404 routes.
Generate a 404 page:
ng generate component page-not-found
Step 10: Route Guards
Route guards control access to routes based on authentication or other conditions.
Create an AuthGuard
:
ng generate guard auth
Implement canActivate
:
import { Injectable } from '@angular/core';
import { CanActivate, Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private router: Router) { }
canActivate(): boolean {
const isLoggedIn = false; // Replace with real authentication
if (!isLoggedIn) {
this.router.navigate(['/']);
return false;
}
return true;
}
}
Apply guard to a route:
{ path: 'dashboard', component: DashboardComponent, canActivate: [AuthGuard] }
Step 11: Lazy Loading Modules
Lazy loading improves performance by loading feature modules only when needed.
Generate a module:
ng generate module admin --route admin --module app.module
Angular CLI will configure lazy loading automatically:
{ path: 'admin', loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) }
Step 12: Query Parameters
Query parameters allow passing additional data via URL: /products?id=1&category=electronics
.
Access query parameters:
import { ActivatedRoute } from '@angular/router';
this.route.queryParams.subscribe(params => {
console.log(params['id']);
console.log(params['category']);
});
Navigate with query parameters:
this.router.navigate(['/products'], { queryParams: { id: 1, category: 'electronics' } });
Step 13: Programmatic Navigation
You can navigate programmatically using the Router
service:
constructor(private router: Router) { }
goHome() {
this.router.navigate(['/']);
}
goToAbout() {
this.router.navigate(['/about']);
}
Step 14: Advanced Router Features
- Preloading strategies: Improve lazy loading by preloading modules in the background.
- CanDeactivate guard: Prevent users from leaving a route with unsaved changes.
- Custom URL matching: Match routes with custom logic.
Example of CanDeactivate:
export interface CanComponentDeactivate {
canDeactivate: () => boolean;
}
Apply in routes:
{ path: 'edit', component: EditComponent, canDeactivate: [PendingChangesGuard] }
Step 15: Best Practices
- Always use
RouterModule.forRoot()
only in the root module. - Use lazy loading for feature modules.
- Protect routes with guards.
- Use descriptive paths for better SEO.
- Use
routerLink
instead ofhref
to prevent full-page reloads. - Keep route configuration organized in separate files if necessary.
Leave a Reply