A Resolver in Angular helps get data before showing a page. This means the page waits until the data is ready, so users see everything at once without waiting.
Resolver for pre-fetching data in Angular
import { Injectable } from '@angular/core'; import { Resolve } from '@angular/router'; import { Observable } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataResolver implements Resolve<DataType> { constructor(private service: DataService) {} resolve(): Observable<DataType> { return this.service.getData(); } }
The resolver class implements the Resolve interface.
The resolve method returns an Observable with the data to fetch.
import { Resolve } from '@angular/router'; import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class UserResolver implements Resolve<User> { constructor(private userService: UserService) {} resolve() { return this.userService.getUser(); } }
import { Resolve } from '@angular/router'; import { Injectable } from '@angular/core'; @Injectable({ providedIn: 'root' }) export class ProductResolver implements Resolve<Product[]> { constructor(private productService: ProductService) {} resolve() { return this.productService.getProducts(); } }
This example shows a resolver fetching user data before the UserComponent loads. The component then displays the user info immediately.
import { Injectable } from '@angular/core'; import { Resolve } from '@angular/router'; import { Observable, of } from 'rxjs'; interface User { id: number; name: string; } @Injectable({ providedIn: 'root' }) export class UserResolver implements Resolve<User> { resolve(): Observable<User> { // Simulate fetching user data return of({ id: 1, name: 'Alice' }); } } // In routing module import { Routes } from '@angular/router'; import { UserComponent } from './user.component'; import { UserResolver } from './user.resolver'; export const routes: Routes = [ { path: 'user', component: UserComponent, resolve: { userData: UserResolver } } ]; // In UserComponent import { Component } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; @Component({ selector: 'app-user', template: `<h1>User Info</h1><p>ID: {{user?.id}}</p><p>Name: {{user?.name}}</p>` }) export class UserComponent { user?: User; constructor(private route: ActivatedRoute) { this.user = this.route.snapshot.data['userData']; } }
Resolvers help avoid showing empty pages while waiting for data.
If the resolver fails, you can handle errors before the page loads.
Resolvers work well with Angular's routing system to improve user experience.
Resolvers fetch data before a route loads to show complete pages.
They return Observables or Promises with the needed data.
Use resolvers to improve user experience by avoiding loading delays on pages.
Practice
Solution
Step 1: Understand Resolver role
Resolvers are designed to fetch data before a route activates, ensuring the page has all needed data upfront.Step 2: Compare options
Only To fetch data before the route loads so the page shows complete information describes this pre-fetching behavior. Other options describe unrelated tasks.Final Answer:
To fetch data before the route loads so the page shows complete information -> Option BQuick Check:
Resolver purpose = pre-fetch data [OK]
- Confusing resolvers with guards for authentication
- Thinking resolvers manage styles or layouts
- Assuming resolvers run after the component loads
Solution
Step 1: Check Resolver interface implementation
The Resolver must implement Resolve<T> and define a resolve method with route parameter returning Observable or Promise.Step 2: Validate method signature
export class DataResolver implements Resolve<Data> { resolve(route: ActivatedRouteSnapshot): Observable<Data> { return this.service.getData(); } } correctly implements Resolve<Data> with resolve(route: ActivatedRouteSnapshot): Observable<Data>. Others miss interface, method name, or return type.Final Answer:
export class DataResolver implements Resolve<Data> { resolve(route: ActivatedRouteSnapshot): Observable<Data> { return this.service.getData(); } } -> Option CQuick Check:
Resolver syntax = implements Resolve<T> + resolve() [OK]
- Missing the Resolve interface implementation
- Using wrong method name instead of resolve
- Returning data directly instead of Observable or Promise
export class UserResolver implements Resolve<User> {
constructor(private userService: UserService) {}
resolve(route: ActivatedRouteSnapshot): Observable<User> {
const id = route.paramMap.get('id')!;
return this.userService.getUserById(id);
}
}Solution
Step 1: Analyze resolve method return type
The resolve method returns this.userService.getUserById(id), which returns Observable<User> as per signature.Step 2: Understand data type returned
The resolved data is a User object wrapped inside an Observable, not a string or array.Final Answer:
A User object wrapped in an Observable -> Option DQuick Check:
Resolver returns Observable<User> [OK]
- Confusing the route param with resolved data
- Assuming it returns a Promise or plain value
- Thinking it returns an array instead of single object
export class ProductResolver implements Resolve<Product> {
constructor(private productService: ProductService) {}
resolve(route: ActivatedRouteSnapshot): Product {
const id = route.paramMap.get('id')!;
this.productService.getProduct(id).subscribe(product => {
return product;
});
}
}Solution
Step 1: Check resolve method return type
The resolve method declares it returns Product but actually returns nothing because subscribe is asynchronous and returns void.Step 2: Understand correct return for resolver
Resolvers must return Observable<Product> or Promise<Product>, not void. Using subscribe inside resolve breaks this contract.Final Answer:
The resolve method returns void instead of Product or Observable<Product> -> Option AQuick Check:
Resolvers must return Observable or Promise, not void [OK]
- Using subscribe inside resolve instead of returning Observable
- Returning wrong data type from resolve
- Ignoring asynchronous nature of data fetching
Solution
Step 1: Understand Angular route resolver configuration
Angular allows multiple resolvers in route config by assigning each resolver to a unique key in the 'resolve' object.Step 2: Access resolved data in component
The component can then access both resolved data objects via ActivatedRoute's data property using the keys.Step 3: Evaluate other options
Create one resolver that calls both services and merges data into one object is possible but less modular. Call one resolver inside another resolver's resolve method is not standard practice. Use a guard to fetch data instead of resolvers uses guards, which are not for data pre-fetching.Final Answer:
Use multiple resolvers in the route config with different keys, then access both in the component -> Option AQuick Check:
Multiple resolvers = multiple keys in route config [OK]
- Trying to chain resolvers inside each other
- Merging data manually instead of using multiple resolvers
- Using guards instead of resolvers for data fetching
Ready to prove it?
Pass the test and this pattern moves unknown
