Routing and Navigation
Level: Intermediate
- Router configuration
- Route parameters
- Navigation programmatically
- Lazy loading routes
- Route guards intro
- SMS app routing
Router Setup
// app.routes.ts
import { Routes } from '@angular/router';
import { StudentListComponent } from './components/student-list/student-list.component';
import { StudentDetailComponent } from './components/student-detail/student-detail.component';
import { StudentFormComponent } from './components/student-form/student-form.component';
export const routes: Routes = [
{ path: '', redirectTo: '/students', pathMatch: 'full' },
{ path: 'students', component: StudentListComponent },
{ path: 'students/:id', component: StudentDetailComponent },
{ path: 'students/:id/edit', component: StudentFormComponent },
{ path: '**', redirectTo: '/students' }
];
Routes array defines paths and components.
:id = route parameter.
** = catch-all (not found).
Router Module
// app.config.ts (standalone)
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes)
]
};
Navigation
Template Navigation
<!-- app.component.html -->
<nav>
<a routerLink="/students">All Students</a>
<a [routerLink]="['/students', student.id]">View Student</a>
</nav>
<router-outlet></router-outlet>
routerLink = navigate to route.
router-outlet = displays current component.
Programmatic Navigation
import { Router } from '@angular/router';
export class StudentListComponent {
constructor(private router: Router) {}
viewStudent(id: number) {
this.router.navigate(['/students', id]);
}
editStudent(id: number) {
this.router.navigateByUrl(`/students/${id}/edit`);
}
}
navigate() = programmatic navigation.
navigateByUrl() = by full URL.
Route Parameters
import { ActivatedRoute } from '@angular/router';
export class StudentDetailComponent implements OnInit {
studentId: number | null = null;
student: any;
constructor(
private route: ActivatedRoute,
private studentService: StudentService
) {}
ngOnInit() {
this.route.params.subscribe(params => {
this.studentId = params['id'];
if (this.studentId) {
this.loadStudent(this.studentId);
}
});
}
loadStudent(id: number) {
this.studentService.getStudent(id).subscribe(
data => this.student = data
);
}
}
ActivatedRoute.params = access route parameters.
Query Parameters
// Navigate with query params
this.router.navigate(['/students'], { queryParams: { class: '10', sort: 'name' } });
// URL: /students?class=10&sort=name
// Read query params
this.route.queryParams.subscribe(params => {
const className = params['class'];
const sortBy = params['sort'];
});
Nested Routes
export const routes: Routes = [
{
path: 'students',
component: StudentLayoutComponent,
children: [
{ path: '', component: StudentListComponent },
{ path: ':id', component: StudentDetailComponent },
{ path: ':id/edit', component: StudentFormComponent }
]
}
];
Nested routes under layout component.
Lazy Loading
export const routes: Routes = [
{
path: 'students',
loadChildren: () => import('./modules/student/student.routes').then(m => m.STUDENT_ROUTES)
},
{
path: 'exams',
loadChildren: () => import('./modules/exam/exam.routes').then(m => m.EXAM_ROUTES)
}
];
loadChildren = load routes only when accessed.
Reduces initial bundle size.
SMS Routing Example
export const routes: Routes = [
{ path: '', redirectTo: '/dashboard', pathMatch: 'full' },
{
path: 'dashboard',
component: DashboardComponent
},
{
path: 'students',
component: StudentLayoutComponent,
children: [
{ path: '', component: StudentListComponent },
{ path: 'new', component: StudentFormComponent },
{ path: ':id', component: StudentDetailComponent },
{ path: ':id/edit', component: StudentFormComponent }
]
},
{
path: 'exams',
component: ExamLayoutComponent,
children: [
{ path: '', component: ExamListComponent },
{ path: ':id', component: ExamDetailComponent }
]
},
{
path: 'fees',
loadChildren: () => import('./modules/fee/fee.routes').then(m => m.FEE_ROUTES)
}
];
Key Takeaways
Routes= array of path-component mappings:param= route parameterrouterLink= navigate in templatesRouter.navigate()= programmatic navigationActivatedRoute= access current route inforouter-outlet= render component- Lazy loading = load routes on demand
- Query params = optional filtering
Angular routing similar to ASP.NET Core attribute routing. Nested routes like Area structure. Same concepts, different syntax.
- Not including router-outlet — Component not displayed
- Forgetting :param syntax — Route not working
- Wrong pathMatch — Redirects not working
- Not unsubscribing from params — Memory leaks
Use ChatGPT, Claude, or Copilot to go deeper on Angular Routing. Try these prompts:
"Why use router-outlet instead of component selector?""How do you pass data between routes?""What's benefit of lazy loading?""Quiz me on routing"
💡 Tip: After reading this article, paste your own code into AI and ask "What could go wrong here and why?" — fastest way to find edge cases and deepen understanding.