Routing
Routing allows user to navigate to different part of application
It keeps your application linkable and bookmarkable
Allows you to maintain state of application
Allows to crate modular application ( every modules defies it's own route )
Allows to implement authoriation ( certain roles have access to certain urls )
Note
Routing is optional, we can build an application that never changes the url
Configuring Route
<head>
<base href="/">
</head>
// routes.ts
import { RouterModule, Routes } from '@angular/router';
const routes: Routes = [
{ path: 'home', component: "HomeComponent"},
{ path: 'about', component: "AboutComponent"}
];
export const routing = RouterModule.forRoot(routes);
path: URL to be shown in the browser when aplication is on specific route
component: Component displayed when user is on particular route
redirectTo: redirect route if needed
pathMatch: optional property to match full url or just the beggning
children: array of route definition object represting child routes
Using Router
import { routing } from './app.routes';
@NgModule({
imports: [ BrowserModule, routing ],
declarations: [ AppComponent, HomeComponent ],
bootstrap: [ AppComponent ]
})
export class AppModule {}
Redirecting the router to another route
When your application starts, it navigates to empty route by default, we can configure router to redirect to a named route by default.
const routes: Routes = [
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'home', component: "HomeComponent"},
{ path: 'about', component: "AboutComponent"}
];
Defining links between routes
<a [routerLink]="/home">Home</a>
<router-outlet></router-outlet> <!-- route components added here -->
Alternatively you can navigate to route by calling navigate
function on router
this.router.navigate(['/home']);
Route Parameter
const routes: Routes = [
{ path: 'product-detail/:id', component: "ProductDetailComponent" }
];
Access route parameter from component
ActivatedRoute
service provides a params Observable which we can subscribe to get the route parameters.
import { ActivatedRoute } from '@angular/router';
@Component({})
export class ProductDetailComponent{
constructor(private route: ActivatedRoute){ }
ngOnInit(){
this.routeSubscription = this.route.params.subscribe(params => {
this.productId = +params['id'];
});
}
ngOnDestroy(){
this.routeSubscription.unsubscribe();
}
}
Router trigger ( from HTML )
<a [routerLink]="['product-detail', productId]">
{{ product.name }}
</a>
Child Routes
Specify child route by using the children
route property
const routes: Routes = [
{
path: 'product-detail/:id',
component: "ProductDetailComponent"
children: [
{ path: '', redirectTo: 'overview', pathMatch: 'full' },
{ path: 'overview', component: OverviewComponent },
{ path: 'specs', component: SpecsComponent },
]
}
];
This will create following API structure
product-detail/3/overview
product-detail/3/specs
Child route placeholder
Child route requires additional router-outlet
just like we used in root application
@Component({
selector: 'product-detail',
template: `
<h1>Product Detail: {{ productId }}</h1>
<router-outlet></router-outlet> <!-- Overview & specs component get added here by router -->
`
})
Access parent route parameter from child router
export class Overview{
constructor(private router: Router, route: ActivatedRoute){}
ngOnInit(){
this.subscription = this.router.routerState.parent(this.route)
.params.subscribe(params => {
this.parentProductId = this.params['id'];
})
}
}
Passing query parameter
<a [routerLink]="['product-list']" [queryParams]="{page: 99 }">Go to page 99</a>
Alternatively we can navigate programmatically using Router
service
goToPage(){
this.router.navigate(['/product-list'], {queryParams: {page: 99 }});
}
Reading query parameters
import { ActivatedRoute } from '@angular/router';
@Component({})
export class ProductDetailComponent{
constructor(private route: ActivatedRoute){ }
ngOnInit(){
this.routeSubscription = this.route.queryParams.subscribe(params => {
this.page = +params['page'] || 0;
});
}
}
Protecting route with guards
CanActivate: gaurd navigation to a route
CanDeactivate: gaurd navigation from a route
Resolve: pre-fetch data before activating a route
CanLoad: Prevent asynchronous routing
Step 1- Create a Gaurd
import { Injectable } from '@angular/core';
import { CanActivate } from '@angular/router';
@Injectable()
export class ProductDetailGuard implements CanActivate{
CanActivate(route: ActivatedRouteSnapshot): boolean{
// route.url[1].path
}
}
Step 2 - Registering a guard
import { ProductDetailGuard } from './products/product-guard.service';
@NgModule({
providers: [ ProductDetailGuard ],
bootstrap: [ AppComponent ]
})
export class AppModule{}
Step 3 - Using a guard
// routes.ts
const routes: Routes = [
{
path: 'products/:id',
canActivate: ProductDetailGuard,
component: ProductDetailComponent
},
{
path: 'home',
component: HomeComponent
}
];
Last updated
Was this helpful?