Skip to content

Commit 07336e7

Browse files
bencodezenAndrewKushnir
authored andcommitted
docs: add dedicated routing lifecycle and events guide (angular#62225)
doc: apply suggestions from code review Co-authored-by: Enea Jahollari <jahollarienea14@gmail.com> Co-authored-by: Matthieu Riegler <kyro38@gmail.com> PR Close angular#62225
1 parent 4b614fb commit 07336e7

File tree

2 files changed

+248
-0
lines changed

2 files changed

+248
-0
lines changed

adev/src/app/sub-navigation-data.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,11 @@ const DOCS_SUB_NAVIGATION_DATA: NavigationItem[] = [
361361
path: 'guide/routing/route-guards',
362362
contentPath: 'guide/routing/route-guards',
363363
},
364+
{
365+
label: 'Lifecycle and events',
366+
path: 'guide/routing/lifecycle-and-events',
367+
contentPath: 'guide/routing/lifecycle-and-events',
368+
},
364369
{
365370
label: 'Other routing tasks',
366371
path: 'guide/routing/common-router-tasks',
Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
# Router Lifecycle and Events
2+
3+
Angular Router provides a comprehensive set of lifecycle hooks and events that allow you to respond to navigation changes and execute custom logic during the routing process.
4+
5+
## Common router events
6+
7+
The Angular Router emits navigation events that you can subscribe to in order to track the navigation lifecycle. These events are available through the `Router.events` observable. This section covers common routing lifecycle events for navigation and error tracking (in chronological order).
8+
9+
| Events | Description |
10+
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
11+
| [`NavigationStart`](api/router/NavigationStart) | Occurs when navigation begins and contains the requested URL. |
12+
| [`RoutesRecognized`](api/router/RoutesRecognized) | Occurs after the router determines which route matches the URL and contains the route state information. |
13+
| [`GuardsCheckStart`](api/router/GuardsCheckStart) | Begins the route guard phase. The router evaluates route guards like `canActivate` and `canDeactivate`. |
14+
| [`GuardsCheckEnd`](api/router/GuardsCheckEnd) | Signals completion of guard evaluation. Contains the result (allowed/denied). |
15+
| [`ResolveStart`](api/router/ResolveStart) | Begins the data resolution phase. Route resolvers start fetching data. |
16+
| [`ResolveEnd`](api/router/ResolveEnd) | Data resolution completes. All required data becomes available. |
17+
| [`NavigationEnd`](api/router/NavigationEnd) | Final event when navigation completes successfully. The router updates the URL. |
18+
| [`NavigationSkipped`](api/router/NavigationSkipped) | Occurs when the router skips navigation (e.g., same URL navigation). |
19+
20+
The following are common error events:
21+
22+
| Event | Description |
23+
| ------------------------------------------------- | -------------------------------------------------------------------------------- |
24+
| [`NavigationCancel`](api/router/NavigationCancel) | Occurs when the router cancels navigation. Often due to a guard returning false. |
25+
| [`NavigationError`](api/router/NavigationError) | Occurs when navigation fails. Could be due to invalid routes or resolver errors. |
26+
27+
For a list of all lifecycle events, check out the [complete table of this guide](#all-router-events).
28+
29+
## How to subscribe to router events
30+
31+
When you want to run code during specific navigation lifecycle events, you can do so by subscribing to the `router.events` and checking the instance of the event:
32+
33+
```ts
34+
// Example of subscribing to router events
35+
import { Component, inject, signal, effect } from '@angular/core';
36+
import { Event, Router, NavigationStart, NavigationEnd } from '@angular/router';
37+
38+
@Component({ ... })
39+
export class RouterEventsComponent {
40+
private readonly router = inject(Router);
41+
42+
constructor() {
43+
// Subscribe to router events and react to events
44+
this.router.events.pipe(takeUntilDestroyed()).subscribe((event: Event) => {
45+
if (event instanceof NavigationStart) {
46+
// Navigation starting
47+
console.log('Navigation starting:', event.url);
48+
}
49+
if (event instanceof NavigationEnd) {
50+
// Navigation completed
51+
console.log('Navigation completed:', event.url);
52+
}
53+
});
54+
}
55+
}
56+
```
57+
58+
Note: The [`Event`](api/router/Event) type from `@angular/router` is named the same as the regular global [`Event`](https://developer.mozilla.org/en-US/docs/Web/API/Event) type, but it is different from the [`RouterEvent`](api/router/RouterEvent) type.
59+
60+
## How to debug routing events
61+
62+
Debugging router navigation issues can be challenging without visibility into the event sequence. Angular provides a built-in debugging feature that logs all router events to the console, helping you understand the navigation flow and identify where issues occur.
63+
64+
When you need to inspect a Router event sequence, you can enable logging for internal navigation events for debugging. You can configure this by passing a configuration option (`withDebugTracing()`) that enables detailed console logging of all routing events.
65+
66+
```ts
67+
import { provideRouter, withDebugTracing } from '@angular/router';
68+
69+
const appRoutes: Routes = [];
70+
bootstrapApplication(AppComponent,
71+
{
72+
providers: [
73+
provideRouter(appRoutes, withDebugTracing())
74+
]
75+
}
76+
);
77+
```
78+
79+
For more information, check out the official docs on [`withDebugTracing`](api/router/withDebugTracing).
80+
81+
## Common use cases
82+
83+
Router events enable many practical features in real-world applications. Here are some common patterns that are used with router events.
84+
85+
### Loading indicators
86+
87+
Show loading indicators during navigation:
88+
89+
```angular-ts
90+
import { Component, inject } from '@angular/core';
91+
import { Router } from '@angular/router';
92+
import { toSignal } from '@angular/core/rxjs-interop';
93+
import { map } from 'rxjs/operators';
94+
95+
@Component({
96+
selector: 'app-loading',
97+
template: `
98+
@if (loading()) {
99+
<div class="loading-spinner">Loading...</div>
100+
}
101+
`
102+
})
103+
export class AppComponent {
104+
private router = inject(Router);
105+
106+
readonly loading = toSignal(
107+
this.router.events.pipe(
108+
map(() => !!this.router.getCurrentNavigation())
109+
),
110+
{ initialValue: false }
111+
);
112+
}
113+
```
114+
115+
### Analytics tracking
116+
117+
Track page views for analytics:
118+
119+
```typescript
120+
import { Component, inject, signal, effect } from '@angular/core';
121+
import { Router, NavigationEnd } from '@angular/router';
122+
123+
@Injectable({ providedIn: 'root' })
124+
export class AnalyticsService {
125+
private router = inject(Router);
126+
private destroyRef = inject(DestroyRef);
127+
128+
startTracking() {
129+
this.router.events.pipe(takeUntilDestroyed(this.destroyRef))
130+
.subscribe(event => {
131+
// Track page views when URL changes
132+
if (event instanceof NavigationEnd) {
133+
// Send page view to analytics
134+
this.analytics.trackPageView(url);
135+
}
136+
});
137+
}
138+
139+
private analytics = {
140+
trackPageView: (url: string) => {
141+
console.log('Page view tracked:', url);
142+
}
143+
};
144+
}
145+
```
146+
147+
### Error handling
148+
149+
Handle navigation errors gracefully and provide user feedback:
150+
151+
```angular-ts
152+
import { Component, inject, signal } from '@angular/core';
153+
import { Router, NavigationStart, NavigationError, NavigationCancel, NavigationCancellationCode } from '@angular/router';
154+
155+
@Component({
156+
selector: 'app-error-handler',
157+
template: `
158+
@if (errorMessage()) {
159+
<div class="error-banner">
160+
{{ errorMessage() }}
161+
<button (click)="dismissError()">Dismiss</button>
162+
</div>
163+
}
164+
`
165+
})
166+
export class ErrorHandlerComponent {
167+
private router = inject(Router);
168+
readonly errorMessage = signal('');
169+
170+
constructor() {
171+
this.router.events.pipe(takeUntilDestroyed()).subscribe(event => {
172+
if (event instanceof NavigationStart) {
173+
this.errorMessage.set('');
174+
} else if (event instanceof NavigationError) {
175+
console.error('Navigation error:', event.error);
176+
this.errorMessage.set('Failed to load page. Please try again.');
177+
} else if (event instanceof NavigationCancel) {
178+
console.warn('Navigation cancelled:', event.reason);
179+
if (event.reason === NavigationCancellationCode.GuardRejected) {
180+
this.errorMessage.set('Access denied. Please check your permissions.');
181+
}
182+
}
183+
});
184+
}
185+
186+
dismissError() {
187+
this.errorMessage.set('');
188+
}
189+
}
190+
```
191+
192+
## All router events
193+
194+
For reference, here is the complete list of all router events available in Angular. These events are organized by category and listed in the order they typically occur during navigation.
195+
196+
### Navigation events
197+
198+
These events track the core navigation process from start through route recognition, guard checks, and data resolution. They provide visibility into each phase of the navigation lifecycle.
199+
200+
| Event | Description |
201+
| --------------------------------------------------------- | --------------------------------------------------------------- |
202+
| [`NavigationStart`](api/router/NavigationStart) | Occurs when navigation starts |
203+
| [`RouteConfigLoadStart`](api/router/RouteConfigLoadStart) | Occurs before lazy loading a route configuration |
204+
| [`RouteConfigLoadEnd`](api/router/RouteConfigLoadEnd) | Occurs after a lazy-loaded route configuration loads |
205+
| [`RoutesRecognized`](api/router/RoutesRecognized) | Occurs when the router parses the URL and recognizes the routes |
206+
| [`GuardsCheckStart`](api/router/GuardsCheckStart) | Occurs at the start of the guard phase |
207+
| [`GuardsCheckEnd`](api/router/GuardsCheckEnd) | Occurs at the end of the guard phase |
208+
| [`ResolveStart`](api/router/ResolveStart) | Occurs at the start of the resolve phase |
209+
| [`ResolveEnd`](api/router/ResolveEnd) | Occurs at the end of the resolve phase |
210+
211+
### Activation events
212+
213+
These events occur during the activation phase when route components are being instantiated and initialized. Activation events fire for each route in the route tree, including parent and child routes.
214+
215+
| Event | Description |
216+
| --------------------------------------------------------- | --------------------------------------------- |
217+
| [`ActivationStart`](api/router/ActivationStart) | Occurs at the start of route activation |
218+
| [`ChildActivationStart`](api/router/ChildActivationStart) | Occurs at the start of child route activation |
219+
| [`ActivationEnd`](api/router/ActivationEnd) | Occurs at the end of route activation |
220+
| [`ChildActivationEnd`](api/router/ChildActivationEnd) | Occurs at the end of child route activation |
221+
222+
### Navigation completion events
223+
224+
These events represent the final outcome of a navigation attempt. Every navigation will end with exactly one of these events, indicating whether it succeeded, was cancelled, failed, or was skipped.
225+
226+
| Event | Description |
227+
| --------------------------------------------------- | ------------------------------------------------------------------- |
228+
| [`NavigationEnd`](api/router/NavigationEnd) | Occurs when navigation ends successfully |
229+
| [`NavigationCancel`](api/router/NavigationCancel) | Occurs when the router cancels navigation |
230+
| [`NavigationError`](api/router/NavigationError) | Occurs when navigation fails due to an unexpected error |
231+
| [`NavigationSkipped`](api/router/NavigationSkipped) | Occurs when the router skips navigation (e.g., same URL navigation) |
232+
233+
### Other events
234+
235+
There is one additional event that occurs outside the main navigation lifecycle, but it is still part of the router's event system.
236+
237+
| Event | Description |
238+
| ----------------------------- | ----------------------- |
239+
| [`Scroll`](api/router/Scroll) | Occurs during scrolling |
240+
241+
## Next steps
242+
243+
Learn more about [route guards](/guide/routing/route-guards) and [common router tasks](/guide/routing/common-router-tasks).

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy