Belajar Angular - HTTP & Data Fetching
Episode 8 of 24

Belajar Angular - HTTP & Data Fetching

Episode ini membahas HTTP dan data fetching di Angular: memakai HttpClient untuk integrasi REST API, bekerja dengan Observables dan RxJS, menangani error dengan retry, serta strategi caching dan optimasi request.

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

Pendahuluan

Aplikasi modern hampir tidak pernah berdiri sendiri — mereka membutuhkan data dari server. Angular menyediakan HttpClient untuk komunikasi HTTP, dibangun di atas Observables RxJS yang menjadi pola asinkron utama di seluruh framework.

Episode 8 membahas integrasi REST API dengan HttpClient, bekerja dengan Observables dan operator RxJS, penanganan error dengan retry, serta caching dan optimasi request. Ini adalah keterampilan inti untuk aplikasi yang berhubungan dengan backend.

HttpClient dan Integrasi REST API

Mengaktifkan HttpClient

HttpClient diaktifkan lewat provideHttpClient di app.config.ts:

JSAktifkan HttpClient
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient, withFetch } from '@angular/common/http';
 
export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(withFetch()),
  ],
};

provideHttpClient(withFetch()) mengaktifkan HttpClient sekaligus memakai fetch API modern sebagai engine-nya. Setelah ini, service bisa meng-inject HttpClient.

Request Pertama dengan HttpClient

JSService post dengan HttpClient
import { Injectable, inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Post } from './post.model';
 
@Injectable({ providedIn: 'root' })
export class PostService {
  private readonly http = inject(HttpClient);
  private readonly apiUrl = 'https://jsonplaceholder.typicode.com';
 
  listar(): Observable<Post[]> {
    return this.http.get<Post[]>(`${this.apiUrl}/posts`);
  }
 
  cari(id: number): Observable<Post> {
    return this.http.get<Post>(`${this.apiUrl}/posts/${id}`);
  }
 
  buat(data: Post): Observable<Post> {
    return this.http.post<Post>(`${this.apiUrl}/posts`, data);
  }
}

this.http.get<Post[]>(url) mengembalikan Observable<Post[]>. TypeScript generics di sini bukan jaminan runtime, tetapi membantu kalian menulis kode yang benar. post, put, delete, dan patch mengikuti pola yang sama.

Observables, RxJS, dan Data Streams

Subscribe di Komponen

Observable tidak berjalan sampai di-subscribe. Pola umum di komponen: panggil method service, subscribe, lalu simpan hasilnya.

JSSubscribe Observable di komponen
import { Component, inject, signal, OnInit } from '@angular/core';
import { PostService } from './post.service';
 
@Component({
  selector: 'app-post-list',
  standalone: true,
  template: `
    @for (post of posts(); track post.id) {
      <p>{{ post.title }}</p>
    }
  `,
})
export class PostListComponent implements OnInit {
  private readonly postService = inject(PostService);
  readonly posts = signal<Post[]>([]);
 
  ngOnInit(): void {
    this.postService.listar().subscribe({
      next: (data) => this.posts.set(data),
      error: (err) => console.error('Gagal memuat post', err),
    });
  }
}

Hasil HTTP disimpan ke signal sehingga template bereaksi terhadap perubahan. Perhatikan handler error — tanpa ini, error HTTP akan menjadi uncaught error di console.

Operator RxJS untuk Pipeline Data

RxJS adalah pipeline transformasi. Beberapa operator yang paling sering dipakai bersama HttpClient:

JSPipeline data dengan operator RxJS
import { map, tap, catchError, retry, throwError, of } from 'rxjs';
 
this.http.get<Post[]>(url).pipe(
  retry({ count: 3, delay: 1000 }),
  map((posts) => posts.filter((p) => p.published)),
  tap((posts) => console.log(`Dimuat ${posts.length} post`)),
  catchError((err) => {
    console.error(err);
    return of([]);
  }),
);

retry({ count: 3, delay: 1000 }) mengulang request tiga kali dengan jeda satu detik untuk error sementara seperti timeout. map mentransformasi data, tap mengeksekusi efek samping, dan catchError menangkap kegagalan — di sini mengembalikan daftar kosong agar UI tidak crash.

Error Handling dan Retry

Membedakan Jenis Error

Error HTTP tidak selalu karena server. HttpErrorResponse membedakan error sisi klien (network) dan sisi server (status code):

JSMenangkap error HTTP secara terpisah
import { HttpErrorResponse } from '@angular/common/http';
import { throwError } from 'rxjs';
 
this.http.get<Post>(url).pipe(
  catchError((err: HttpErrorResponse) => {
    if (err.status === 404) {
      console.error('Data tidak ditemukan');
      return throwError(() => new Error('Post tidak ada'));
    }
    if (err.status >= 500) {
      console.error('Kesalahan server, coba lagi nanti');
      return throwError(() => err);
    }
    console.error('Masalah jaringan atau kesalahan lain', err.message);
    return throwError(() => err);
  }),
);

err.status === 404 menandai data tidak ditemukan, sementara status 500 menandai masalah server yang mungkin sementara. throwError meneruskan error ke subscriber agar UI bisa menampilkan pesan yang sesuai.

Caching dan Optimasi Request

Caching dengan RxJS

Tanpa caching, setiap komponen yang butuh data yang sama akan melakukan request berulang. Gunakan operator shareReplay untuk menyimpan hasil dan membagikannya:

JSCaching sederhana dengan shareReplay
import { shareReplay } from 'rxjs';
 
private readonly cache$ = this.http.get<Post[]>(url).pipe(shareReplay(1));
 
listar(): Observable<Post[]> {
  return this.cache$;
}

shareReplay(1) membuat request dijalankan sekali lalu hasilnya disimpan dan dibagikan ke semua subscriber berikutnya. Ini adalah bentuk caching paling sederhana di level data stream.

Optimasi Request

Beberapa praktik optimasi: gunakan distinctUntilChanged untuk menghindari request duplikat, kombinasikan request paralel dengan forkJoin atau combineLatest, batalkan request tidak terpakai dengan switchMap, dan bersihkan subscription di ngOnDestroy. Detail caching lebih dalam, termasuk cache invalidation dan HTTP interceptor, akan dibahas di episode 14.

Penutup

Inti yang harus dibawa pulang:

  • provideHttpClient mengaktifkan HttpClient di aplikasi standalone.
  • HttpClient mengembalikan Observable yang baru berjalan saat di-subscribe.
  • retry, map, tap, dan catchError membentuk pipeline data yang aman.
  • Bedakan error jaringan, 404, dan error server lewat HttpErrorResponse.
  • shareReplay memberikan caching sederhana untuk data yang jarang berubah.
  • Optimasi request memakai switchMap, forkJoin, dan pembatalan subscription.

Di episode 9 selanjutnya kita akan membahas routing dan navigasi — memakai Angular Router, menyusun route configuration dengan child routes dan lazy loading, melindungi rute dengan guards dan resolver, serta mengelola query params, fragment, dan navigation extras.