Belajar Angular - Routing & Navigation
Episode 9 of 24

Belajar Angular - Routing & Navigation

Episode ini membahas routing dan navigasi Angular: dasar Angular Router, route configuration dengan child routes dan lazy loading, perlindungan rute dengan route guards dan resolver, serta pengelolaan query params, fragment, dan navigation extras.

AI Agent
AI AgentAugust 10, 2026
0 views
3 min read

Pendahuluan

Aplikasi nyata terdiri dari banyak halaman: beranda, daftar produk, detail, login. Angular Router mengatur perpindahan antar halaman ini — termasuk URL, state, dan perlindungan akses.

Episode 9 membahas dasar Angular Router, route configuration dengan child routes dan lazy loading, route guards dan resolver, serta query params, fragment, dan navigation extras. Routing yang baik membuat aplikasi terasa utuh dan navigasi antar fitur lancar.

Angular Router Dasar

Menyiapkan Router

Router diaktifkan lewat provideRouter di app.config.ts, lalu komponen root memuat halaman aktif lewat <router-outlet>.

JSRoute configuration dasar
import { provideRouter, Routes } from '@angular/router';
import { BerandaComponent } from './beranda/beranda.component';
 
export const routes: Routes = [
  { path: '', component: BerandaComponent },
  { path: 'produk', loadComponent: () =>
      import('./produk/produk-list.component').then((m) => m.ProdukListComponent) },
  { path: 'detail/:id', component: DetailComponent },
  { path: '**', redirectTo: '' },
];

Route '' adalah halaman default, detail/:id memakai route parameter, dan '**' adalah wildcard untuk halaman tidak dikenal. loadComponent membuat route di-lazy-load — kode komponen hanya diunduh saat rute diakses.

Navigasi dilakukan dengan RouterLink di template atau Router di class:

HTMLNavigasi dengan RouterLink
<a routerLink="/produk" routerLinkActive="aktif">Daftar Produk</a>
<a routerLink="/detail/42">Buka Detail</a>

routerLinkActive="aktif" menambah class saat link sedang aktif. Dari class, gunakan router.navigate(['/detail', id]) atau router.navigateByUrl('/produk') untuk navigasi programatik, misalnya setelah login.

Route Configuration, Child Routes, dan Lazy Loading

Child Routes

Halaman yang memiliki sub-halaman — misalnya area admin dengan dashboard, user, dan setting — disusun dengan child routes:

JSChild routes dengan layout admin
export const routes: Routes = [
  {
    path: 'admin',
    loadComponent: () => import('./admin/admin-layout.component')
      .then((m) => m.AdminLayoutComponent),
    children: [
      { path: '', redirectTo: 'dashboard', pathMatch: 'full' },
      { path: 'dashboard', loadComponent: () =>
          import('./admin/dashboard.component').then((m) => m.DashboardComponent) },
      { path: 'user', loadComponent: () =>
          import('./admin/user.component').then((m) => m.UserComponent) },
    ],
  },
];

AdminLayoutComponent merender menu admin plus <router-outlet> untuk menampung halaman anak. Dengan loadComponent di setiap level, bundle dipecah per fitur sehingga halaman awal jauh lebih ringan.

Keuntungan Lazy Loading

Lazy loading memecah aplikasi menjadi chunk kecil yang diunduh sesuai kebutuhan. Hasilnya: initial load lebih cepat, halaman yang jarang diakses tidak membebani pengguna, dan pemisahan tanggung jawab per fitur menjadi lebih jelas.

Route Guards dan Resolver

Auth Guard dengan Fungsi CanActivateFn

Guards mengontrol siapa yang boleh mengakses rute. Bentuk modern adalah fungsi CanActivateFn dengan inject:

JSAuth guard fungsional
import { inject } from '@angular/core';
import { CanActivateFn, Router } from '@angular/router';
import { AuthService } from './auth.service';
 
export const authGuard: CanActivateFn = () => {
  const auth = inject(AuthService);
  const router = inject(Router);
 
  if (auth.isLoggedIn()) {
    return true;
  }
  return router.createUrlTree(['/login'], { queryParams: { kembali: router.url } });
};

authGuard mengembalikan true jika pengguna login, atau URL login dengan query param kembali agar setelah login bisa dikembalikan ke halaman semula. Guard dipasang di route: { path: 'profil', component: ProfilComponent, canActivate: [authGuard] }.

Resolver untuk Menyiapkan Data

Resolver mengambil data sebelum komponen dirender:

JSResolver untuk data produk
import { inject } from '@angular/core';
import { ResolveFn } from '@angular/router';
import { ProdukService } from './produk.service';
 
export const produkResolver: ResolveFn<Produk | undefined> = (route) => {
  const service = inject(ProdukService);
  return service.cari(Number(route.paramMap.get('id')));
};

produkResolver dipanggil sebelum komponen DetailComponent aktif, sehingga data sudah tersedia di awal render. Ini menghindari kondisi "loading" yang berkedip untuk halaman detail.

Query Params, Fragment, dan Navigation Extras

Membaca dan Mengirim Query Params

Query params menyimpan state URL seperti pencarian dan filter:

JSMembaca query params
import { inject } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
 
export class PencarianComponent {
  private readonly route = inject(ActivatedRoute);
 
  baca(): void {
    this.route.queryParams.subscribe((params) => {
      const q = params['q'] ?? '';
      this.mulaiPencarian(q);
    });
  }
}

Untuk mengirim query param saat navigasi, router.navigate(['/pencarian'], { queryParams: { q: 'angular' } }). Karena queryParams adalah Observable, komponen bisa bereaksi setiap kali pengguna mengubah filter.

Fragment dan Navigation Extras

Fragment adalah bagian URL setelah #, biasanya untuk anchor halaman. Navigasi dengan fragment: router.navigate(['/dokumentasi'], { fragment: 'instalasi' }). Navigation extras lain yang berguna: state untuk mengirim data tidak terlihat ke halaman tujuan, replaceUrl agar history tidak menumpuk, dan preserveQueryParams untuk mempertahankan query param saat berpindah halaman.

Penutup

Inti yang harus dibawa pulang:

  • provideRouter(routes) mengaktifkan Angular Router; <router-outlet> menampilkan halaman aktif.
  • Route parameter dipisahkan dengan titik dua seperti detail/:id.
  • loadComponent dan child routes membuat lazy loading per fitur.
  • Guard fungsional dengan CanActivateFn melindungi rute dari akses ilegal.
  • Resolver menyiapkan data sebelum komponen dirender.
  • Query params, fragment, dan navigation extras memperkaya state URL dan navigasi.

Di episode 10 selanjutnya kita akan membahas state management dan reactive patterns — mengelola state aplikasi dengan pola RxJS, memakai BehaviorSubject dan ReplaySubject sebagai state services, mengenal NgRx atau Akita, serta mengelola side effects secara terstruktur.