⚙️ Simplifying Navigation Error Handling with Angular’s Upcoming Feature⚙️
You can read this article on Medium as well if you wish!
Angular is set to introduce a new navigation error handler feature, allowing developers to create more robust applications and handle navigation errors easier with more ergonomic API🤗.
Legacy navigation handler
Previously, in order to handle NavigationError
developers had to manually subscribe
to the router’s events, and then filter the results to capture only navigation errors 🤦♂️. On example of such implementation is often seen right in AppComponent
:
export class AppComponent implements OnInit {
// alternatively you could use contsructor injection
private readonly _router = inject(Router);
// Legacy approach that will be deprecated soon
ngOnInit() {
this._router.events
.pipe(filter((event) => event instanceof NavigationError))
.subscribe(() =>
// Handling NavigationError, e.g. redirect to error route
this._router.navigate(["error"], { skipLocationChange: true })
);
}
}
You can find full stackblitz example here. Trying to access Home route will produce NavigationError. GL HF!
This manual process had following drawbacks:
- Manual process was time-consuming and prone to errors 🤔
- Required more setup ⚙️
- Cluttered component/module with unrelated logic 🔐
- Required more knowledge increasing learning curve for new developers 📈
New Era
The new feature, enabled through the withNavigationErrorHandler
function, provides developers with more ergonomic way to tackle this problems.
The idea behind it according to angular core team:
withErrorHandler
is a close replacement for the
RouterModule.forRoot.errorHandler
/Router.errorHandler
.
It provides a quick, short way for users to define a function to handle
NavigationError
events. — angular source code
See below is a basic example how you can use it in your **standalone**
application:
bootstrapApplication(AppComponent, {
providers: [
provideRouter(
appRoutes,
// new API goes here!!!
withNavigationErrorHandler((err: NavigationError) =>
inject(NavErrorHandler).handle(err)
)
),
],
});
The main benefit of this new feature is that it offers developers an easier, more ergonomic and more reliable way of handling navigation errors 🔐.
As you can see, the new feature can leverage the inject
function 💉, which is possible due to the fact that under the hood withNavigationErrorHandler
utilizes the EnvironmentInjector.runInContext
API 💻.
Source code with my comments for **withNavigationErrorHandler**
looks like this:
export function withNavigationErrorHandler(
fn: (error: NavigationError) => void
): NavigationErrorHandlerFeature {
const providers = [
{
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useValue: () => {
const injector = inject(EnvironmentInjector);
// takes responsibility to react to specific RouterEvent: NavigationError
inject(Router).events.subscribe((e) => {
if (e instanceof NavigationError) {
// enables to use inject function in withNavigationErrorHandler
injector.runInContext(() => fn(e));
}
});
},
},
];
return routerFeature(
RouterFeatureKind.NavigationErrorHandlerFeature,
providers
);
}
From the source code above you can see that it affectively performs the same thing we used to do in a past but now performing the heavylifting itself letting us to write less boilerplate code, and avoid some rxjs pitfalls along the way.
Conclusion
The new feature is part of the Angular development team’s ongoing efforts to provide developers with better tools to create more robust and easy to design applications 📊. It provides developers with an easier and more ergonomic way of handling navigation errors 🚀!