Reference · Frontend · Angular 16

Angular 16: Service, DI, routing, dan guard

Ringkasan satu halaman. Dari Lesson 0014. Lanjutan dari Angular dasar.

Angular Service + inject

@Injectable({ providedIn: 'root' })
export class ProductService { constructor(private http: HttpClient) {} }

constructor(private products: ProductService) {}   // inject lewat tipe
private products = inject(ProductService);          // atau fungsi inject()

Di mana provider ditulis

TempatInstancePadanan
providedIn: 'root'satu, bersama; tree-shakable (pilihan default)Provider di <App/>; Singleton .NET
@NgModule providerssatu per ModuleInjector (modul lazy = injector anak)gaya sebelum v6
@Component providerssatu per instance component, mati bersamanya<Ctx.Provider> di component itu

Resolusi (DI hierarkis)

ElementInjector component → parent → … → ModuleInjector (root) → platform → NullInjector (error, kecuali @Optional()). Provider pertama yang ditemukan menang, seperti useContext membaca Provider terdekat. Modifier: @Optional, @Self, @SkipSelf, @Host.

Routing

const routes: Routes = [
  { path: 'products', component: ProductListComponent },
  { path: 'products/:id', component: ProductDetailComponent },
  { path: 'admin', canMatch: [authGuard], canActivate: [authGuard],
    loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule) },
  { path: '', redirectTo: 'products', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent },   // terakhir: first-match wins
];
imports: [RouterModule.forRoot(routes)]   // root;  modul fitur: RouterModule.forChild(routes)
AngularReact Router
routerLink="/products"<Link to>
<router-outlet><Outlet />
ActivatedRoute.snapshot.paramMap.get('id') / paramMap.pipe(...)useParams()
router.navigate(['/products', id])navigate()
loadChildren + import()React.lazy

Lazy loading: hapus modul dari imports AppModule, kalau tidak ia ikut bundle awal.

Guard

export const authGuard: CanActivateFn = () => {
  const auth = inject(AuthService), router = inject(Router);
  return auth.isLoggedIn ? true : router.parseUrl('/login');
};
ReturnEfek
truenavigasi lanjut
falseberhenti, user tetap di tempat
UrlTreebatal + navigasi baru (redirect)
Observable / Promiserouter menunggu nilai pertama

canActivate masuk route · canActivateChild masuk child · canDeactivate keluar route · resolve ambil data sebelum aktif · canMatch route dipakai atau tidak (dicek sebelum modul lazy dimuat; canLoad deprecated).

Jebakan interview

  1. Service di providers module yang juga di-import modul lazy → dua instance. Pakai providedIn: 'root'.
  2. RouterModule.forRoot di modul fitur → seharusnya forChild (hanya boleh satu Router).
  3. Wildcard ** di atas route lain → route lain tidak pernah cocok.
  4. Menulis guard baru sebagai class … implements CanActivate → deprecated di v16; pakai CanActivateFn.
  5. Hanya canActivate di route lazy → bundle tetap terunduh; tambah canMatch.
  6. Guard dianggap keamanan → guard hanya navigasi di browser; otorisasi tetap di API.

Sumber: Understanding DI · Hierarchical injectors · Singleton services · Common routing tasks · Lazy loading · Route guards · CanActivate (deprecated) (dokumentasi Angular v16)