In this post, we will learn about routing in Angular in depth. We will start from basics and progress towards passing parameters, using child routes, protecting routes and finally routing modularization.

Introduction To Routing In Angular
Even though an Angular app is a single page appllication (SPA), the routing mechanism plays an important role to load and manage the Angular application. Routing is basically mapping of URLs to Angular components.
Angular routes are declared using Routes
interface which holds an array of defined routes.
const appRoutes: Routes = [
..
]
The declared routes are then imported into Angular app from the AppModule
class:
//inside AppModule
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(appRoutes)
],
...
Routing Basics
1) Use routerLink
to process routes from within the Angular component.
<a routerLink="reset-password">Reset Password</a>
2) Make use of wildcard
path to route paths which are not found or available.
{path: '**', component: NotFoundComponent}
3) The order of route path setup is important. If we use the wildcard at first, all paths will redirect to NotFoundComponent
.
4) Use redirectTo
for redirecting any deprecated routes in the application.
{path: '', redirectTo: 'login', pathMatch:'full'},
5) Use the RouterOutlet
to display the components for the given outlet.
<router-outlet></router-outlet>
Passing Route Parameters In Angular
Parameters can be passed around during routing navigation. This can be achieved in two modes:
- Passing parameters from Angular component
- Passing parameters programmatically
For both cases, parameters must be initially defined during route definition.
{ path: 'details/:id', component: DetailsComponent }
Similarly, multiple parameters can be setup as:
{ path: 'details/:id/:name', component: DetailsComponent }
Passing Parameters From Angular Component
To setup routerLink with parameters, use the [routerLink]
array.
<a [routerLink]="['details', product.id]"> {{product.name}}</div>
Multiple parameters in a similar way:
<a [routerLink]="['details', product.id, 'seller']"> {{product.name}}</a>
Access the parameters from within the component using the ActivatedRoute
class.
constructor(private routes: ActivatedRoute,) {
}
ngOnInit() {
this.routes.params.subscribe(paramteres => {
const id = paramteres['id'];
});
Optional parameters can be added using json objects.
<a [routerLink]="['details', product.id, 'seller', {op1: 'dog', op2: 'cat'}]"> {{product.name}}</a>
Finally, optional parameters can e accessed from component after routing in the same as before:
Passing Parameters Programatically
Use the Router
module to enable passing parameters dynamically from the Angular component.
constructor(private router: Router, private productServices: ProductServices) { }
Then use the navigate
method.
this.router.navigate(['details', id, 'seller']);
Similarly, we can also pass optional parameters:
this.router.navigate(['details', id, 'seller', {op1: 'dogg'}]);
Child Routes In Angular
A child route is basically a route within a route. For example, there can be multiple components within a single Login route:
- Forgot Password component
- Signup component
- Login component
Setup A Child Route In Angular
We can setup child routes in the following way:
{path:'login', component: LoginComponent, children:[
{path:'', component: LoginUserComponent},
{path:'login', component: LoginUserComponent},
{path:'forgot', component: ForgotPasswordComponent},
]},
Or if there any parameters that need to be passed onto child components:
{path:'products', component: ProductsComponent, children: [
{path: 'details/:id', component: DetailsComponent}
]},
A child route can be implemented in the same way as a regular route:
<button routerLink="forgot" routerLinkActive="selected-route">Forgot Password</button>
Furthermore, a relative routing url can also be used to implement child route from parent component.
//called from ForgotPasswordComponent
<a routerLink="../login">Back To Login</a>
In order to make the child routes available, we need to use the RouterOutlet
again at the parent component.
//inside the parent LoginComponent
<router-outlet></router-outlet>
Route Guards In Angular
A route guard is used to protect certain components from unauthorized users. It can tell the router whether or not it should allow navigation to a requested route.
Besides protecting a route, a route guard can also be used to prevent user’s from leaving a certain route.
How To Protect A Route In Angular
The canActivate
property of Route
can be used to protect a route or a child route.
It works with an array of function which resolves to a boolean value. The functions can be observables
, promises
or static functions
.
Start by creating an injectable guard service.
ng g guard services/LoggedIn
This generates a LoggedInGuard
class which implements the CanActivate
interface.
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Observable';
@Injectable()
export class LoggedInGuard implements CanActivate {
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
return true;
}
}
By default, the canActivate
function resolves to true
. You should change the implementation as per your application need.
Now, this service can be implemented in any needed route.
{path: 'admin', component: AdminComponent,
canActivate: [LoggedInGuard],
Also, you need to provide the service via providers
property as it is a injectable service.
providers: [LoggedInGuard],
How To Prevent Deactivating A Route
Similar to protecting route using the canActivate
property, the canDeactivate
property can be used to prevent from routing away from a route.
The implementation for canDeactivate
is quite similar to canActivate
but it does have some differences. You need to inject the component to the service for deactivating it.
Learn more about CanDeactivate
Routing Modularization Using Modules
So far we have been initializing all of routes from AppModule
class itself. Although, there’s nothing wrong with this approach, however, when working on a large project, typically each child routes are defined separately by a ngModule
separately for each parent route.
This pattern of separating Routing Modules for each component is called Routing Modularization in Angular.
Besides maintaining clean code, this practice also helps to improve app performance by lazy loading components.
Setup Routing Module For Components
Generate a routing module using the following command:
ng generate module my_module_name
It generates a template for Angular module:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
@NgModule({
imports: [
CommonModule
],
declarations: []
})
export class AdminModule { }
Next, define all the routes specific to the Admin components.
const appRoutes: Routes = [
{
path: 'admin', component: AdminComponent,
canActivate: [LoggedInGuard],
children: [
{ path: '', component: UsersComponent },
{ path: 'user-list', component: UsersComponent },
{ path: 'add', component: AddUserComponent },
]
}
];
You can implement the canActivate
as before.
Next use the RouterModule
with forChild
method.
//inside AdminModule
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(appRoutes)
],
declarations: [
AdminComponent,
UsersComponent,
AddUserComponent
],
providers:[LoggedInGuard]
})
export class AdminModule { }
Add any needed services as providers and finally use this module in the AppModule
class.
//inside the AppModule class
imports: [
BrowserModule,
AdminModule,
..
Now, the app should work as expected after Routing Modularization.
Lazy Loading Of Modules
Once we have modularized routing, we can set it up to load the components only when required.
For lazy loading, we have to do three things:
- Remove Module import from
AppModule
class. - Add Module as a path specifying the absolute path of the module in the
AppModule
routing declaration. - Remove relative path from Module’s routing.
Below you can see how the module can be imported.
// step 2
//inside the AppModule's routing declaration
{path: 'admin', loadChildren: 'app/admin/admin.module#AdminModule'}
...
// step 1
//inside the AdminModule routing declaration
{ path: '', component: AdminComponent,
...
Wrapping Up Routing In Angular
Ok, now we have covered everything there is to know about Routing in Angular app. To summarize we learnt about:
- Basics Of Routing In Angular
- Passing Parameters
- Routing From Component And Class
- Creating Child Routes
- Protecting Routes
- Routing Modularization
I hope this was a good guide to learn about Routing in Angular. Stay tuned for more content on Angular.
You must be logged in to post a comment.