Data Resolvers

Pre-Fetch Data Before the Route Renders

Data Resolvers

A resolver fetches data while the navigation is in flight, so the component has it ready as soon as it mounts.

5 min read Level 3/5 #angular#router#resolvers
What you'll learn
  • Write a functional ResolveFn
  • Attach it via the resolve key on a route
  • Read resolved data from ActivatedRoute

A resolver is a function that returns data — sync, Promise, or Observable. The route will not activate until the resolver completes, so the component mounts with data already populated.

Define a resolver

import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { UsersService } from './users.service';

export interface User { id: string; name: string }

export const userResolver: ResolveFn<User> = (route) => {
  const id = route.paramMap.get('id')!;
  return inject(UsersService).getOne(id);
};

Attach to the route

export const routes: Routes = [
  {
    path: 'users/:id',
    component: UserComponent,
    resolve: { user: userResolver },
  },
];

Read in the component

import { Component, inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-user',
  standalone: true,
  template: `<h1>{{ user.name }}</h1>`,
})
export class UserComponent {
  private route = inject(ActivatedRoute);
  user = this.route.snapshot.data['user'] as User;
}

When to use resolvers

Resolvers feel tidy but they delay the entire navigation — the user stares at the old page until the data lands. For most UIs, a loading skeleton inside the new component is better UX. Reach for resolvers when you genuinely need the data to render anything meaningful and want to avoid layout shift.

Lazy-Loaded Routes →