Angular Resolver: โหลดข้อมูลก่อนเข้าหน้า

#angular12 เม.ย. 2569

Resolver คืออะไร

Resolver ใช้สำหรับโหลดข้อมูลที่จำเป็นก่อนที่ route จะ activate ทำให้ component ได้รับข้อมูลพร้อมทันทีโดยไม่ต้องแสดง loading state

สร้าง Resolver (Functional)

import { inject } from '@angular/core';
import { ResolveFn, ActivatedRouteSnapshot } from '@angular/router';
import { UserService } from './user.service';

export const userResolver: ResolveFn<User> = (route: ActivatedRouteSnapshot) => {
  const userService = inject(UserService);
  const id = route.paramMap.get('id')!;
  return userService.getUserById(+id);
};

ใช้ใน Routes

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

รับข้อมูลใน Component

import { ActivatedRoute } from '@angular/router';

@Component({
  template: `
    <h1>{{ user.name }}</h1>
    <p>{{ user.email }}</p>
  `
})
export class UserDetailComponent {
  user: User;

  constructor(private route: ActivatedRoute) {
    this.user = this.route.snapshot.data['user'];
  }
}

Resolver กับ Signal

@Component({ ... })
export class UserDetailComponent {
  private route = inject(ActivatedRoute);
  user = toSignal(this.route.data.pipe(map(d => d['user'])));
}

Multiple Resolvers

{
  path: 'dashboard',
  component: DashboardComponent,
  resolve: {
    user: userResolver,
    stats: statsResolver,
    notifications: notificationsResolver
  }
}

Error Handling ใน Resolver

export const userResolver: ResolveFn<User | null> = (route) => {
  const userService = inject(UserService);
  const router = inject(Router);

  return userService.getUserById(+route.paramMap.get('id')!).pipe(
    catchError(() => {
      router.navigate(['/not-found']);
      return of(null);
    })
  );
};

สรุป

Resolver เหมาะกับหน้าที่ต้องการข้อมูลก่อน render เช่น หน้า detail ที่ต้องการ id จาก URL ช่วยให้ UX ดีขึ้นเพราะไม่มี flash of empty content ครับ