javascript / expert
Snippet
Type-Safe Route Parameter Extraction with Resolvers
Functional resolvers replace the deprecated class-based Resolve interface, letting you use inject() to pull dependencies directly inside a plain function passed to the route config. This example guards against malformed route parameters before hitting the service layer, ensuring the component only ever receives a validated Product or null rather than performing ad-hoc parsing in ngOnInit. Because the resolver runs before activation, the component template can assume the data is already present via the route's resolved data, eliminating loading-state flicker for this specific navigation.
snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { ResolveFn, ActivatedRouteSnapshot } from '@angular/router';import { inject } from '@angular/core';import { ProductService } from './product.service';import { Product } from './product.model';export const productResolver: ResolveFn<Product | null> = (route: ActivatedRouteSnapshot) => {const service = inject(ProductService);const id = route.paramMap.get('id');if (!id || !/^[0-9]+$/.test(id)) {return null;}return service.getById(Number(id));};// Route config:// { path: 'product/:id', component: ProductDetail, resolve: { product: productResolver } }
angular
Breakdown
1
export const productResolver: ResolveFn<Product | null> = (route) => {
Defines a functional resolver typed with ResolveFn, receiving the activated route snapshot instead of requiring a class implementing Resolve.
2
const service = inject(ProductService);
Uses inject() inside the function body to access the DI container, avoiding constructor injection entirely since this isn't a class.
3
if (!id || !/^[0-9]+$/.test(id)) { return null; }
Validates the route parameter shape before any service call, preventing malformed IDs from reaching the backend.