bhylu.com

Advertisements

Angular Route Data and Resolvers

A resolver can supply data before a route is activated. It is useful when the screen needs a clear prerequisite, but long or failed work must have a deliberate navigation policy.

How it works

The local resolver supplies a fixed trusted tool summary. The component reads the resolved data under the same key that the route declares. A real resolver using HTTP must validate received data and handle missing records or failures. Do not hold navigation indefinitely waiting for a stream that never supplies a usable result.

Run the code

Use a separate empty project folder with a compatible Node version: ^22.22.3, ^24.15.0 or a supported 26+ runtime. The review uses Node 24.22.1, Angular 22.2.4, CLI/build 22.2.5 and TypeScript 6.0.3. Node 22.15.1 is too old for Angular 22. Save every download at its displayed path; browsers may keep only the basename, so recreate the src folder. Run npm install, npm run build and npm start, then open the loopback address printed by the server. Run npm test for the supplied component tests. These are local teaching projects, not Bhylu publishing files.

The small loopback server serves the compiled app and fixed, read-only tool API fixtures. It is not a database, authentication or lending service. Angular examples do not run in Bhylu’s current HTML or TypeScript playground. No Apache, MySQL or PHP configuration change is needed.

Example

src/app.ts

import { Component } from '@angular/core';
import { inject } from '@angular/core';
import { ActivatedRoute, ResolveFn, RouterOutlet, Routes } from '@angular/router';
const resolveTool: ResolveFn<{ name: string }> = () => ({ name: 'Hand drill' });
@Component({
  selector: 'bh-route-data-part-0',
  standalone: true,
  template: '<p data-result>{{ tool.name }}</p>',
})
class ResolvedPage {
  tool = inject(ActivatedRoute).snapshot.data['tool'] as { name: string };
}
export const routes: Routes = [
  { path: '', component: ResolvedPage, resolve: { tool: resolveTool } },
];
@Component({
  selector: 'bh-route-data',
  standalone: true,
  imports: [RouterOutlet],
  template: `<router-outlet></router-outlet>`,
})
export class App {}

Expected result

Hand drill

The known local resolver contract makes the displayed name available when the route component is created. The assertion describes this controlled route wiring, not a runtime validation of arbitrary JSON. If resolved data can change while the same component remains active, use a reactive data stream instead of assuming a stored snapshot changes automatically.

Supporting source

src/app.config.ts

import { ApplicationConfig, provideZonelessChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app';
export const appConfig: ApplicationConfig = {
  providers: [provideZonelessChangeDetection(), provideRouter(routes)],
};

Advertisements