Javascript Fetch API Async Data Flow JSON Parsing Error Handling
Selesai membaca dokumentasi ini?
Kembali ke rujukan utama JavaScript untuk melanjutkan topik lainnya.
Kembali ke rujukan utama JavaScript untuk melanjutkan topik lainnya.
Fetch API adalah API bawaan JavaScript untuk melakukan request ke server, biasanya untuk mengambil data atau mengirim data lewat HTTP. Di browser modern, fetch() sudah tersedia tanpa library tambahan.
Di praktik harian, fetch dipakai untuk:
XMLHttpRequest di kebanyakan kasus modernKalau alurnya sederhana dan targetnya browser modern, fetch biasanya jadi pilihan default. Kalau butuh fitur yang sangat spesifik seperti progress upload/download yang detail, timeout bawaan yang eksplisit, atau interceptors tingkat library, kadang developer memilih wrapper seperti Axios. Tapi untuk sebagian besar kebutuhan dasar, fetch sudah cukup dan lebih ringan karena native.
Pakai fetch saat kamu perlu kerja HTTP dari JavaScript, misalnya:
Jangan pakai fetch hanya untuk “semua request” tanpa berpikir. Pertimbangkan hal ini:
fetch cocok.fetch tetap cocok, asal kamu siap menulis handling sendiri.fetch atau sediakan polyfill.Prinsipnya: fetch bagus ketika kamu ingin alur request yang eksplisit dan mudah dibaca.
fetch() mengirim request dan mengembalikan Promise. Artinya, hasilnya tidak langsung tersedia di baris yang sama.
Urutan dasarnya begini:
fetch(url, options).Response..json().Yang sering bikin bingung: fetch hanya gagal otomatis kalau ada error network level, misalnya koneksi putus atau request diblokir total. Kalau server membalas 404, 500, atau response error lain, Promise-nya tetap resolved. Karena itu kita harus cek response.ok sendiri.
Kalau dipetakan ke UI, flow yang sehat biasanya seperti ini:
Diagram ini penting karena menunjukkan bahwa request sukses belum tentu berarti data bisa langsung dipakai. Ada beberapa lapisan yang bisa gagal:
fetchasync function loadUsers() {
const response = await fetch('/api/users');
const users = await response.json();
return users;
}Contoh di atas terlihat pendek, tapi masih belum aman sepenuhnya. Kalau server mengembalikan status error, response.json() tetap bisa dipanggil dan kamu bisa saja membaca body error sebagai data sukses. Jadi pola yang lebih sehat biasanya menambahkan pengecekan status.
async function loadUsers() {
const response = await fetch('/api/users');
if (!response.ok) {
throw new Error(`Request gagal: ${response.status} ${response.statusText}`);
Kenapa response.ok penting:
response.ok bernilai true hanya untuk status 2xxKalau ingin lebih jelas, kamu bisa memetakan status tertentu:
async function loadUsers() {
const response = await fetch('/api/users');
if (response.status === 401) {
throw new Error('Sesi habis, silakan login lagi');
}
if (!response.ok) {
Kalau response body berisi JSON, gunakan response.json() untuk mengubah string body menjadi object JavaScript. Method ini juga async, jadi hasilnya perlu di-await.
const response = await fetch('/api/profile');
const data = await response.json();Hal yang perlu diingat:
response.json() hanya cocok kalau body memang JSONjson(), akan muncul error parsingKalau kamu ingin debugging, kadang berguna membaca body sebagai text lebih dulu:
const response = await fetch('/api/profile');
const raw = await response.text();
console.log(raw);Itu membantu saat kamu curiga server sebenarnya mengirim HTML error page, bukan JSON.
async function loadProfile() {
try {
const response = await fetch('/api/profile');
if (!response.ok) {
throw new Error(`Gagal load profile: ${response.status}`);
Pola ini memisahkan dua jenis kegagalan:
fetch() melempar atau Promise gagalDi UI, biasanya error itu diterjemahkan jadi fallback state, misalnya:
loadingdataerrorContohnya:
const state = {
loading: false,
data: null,
error: null,
};
async function refreshUsers() {
state.loading = true;
state.error = null;
response.okIni salah satu jebakan paling umum. Tanpa cek status, response error bisa diproses seperti data normal.
Contoh yang berbahaya:
const response = await fetch('/api/users');
const data = await response.json();Kalau endpoint mengembalikan 404 dengan body JSON error, kode di atas tetap berhasil parse body, padahal isinya bukan data yang diharapkan.
catchTidak semua response error akan masuk catch. Status 404 atau 500 tidak otomatis melempar exception di fetch. Kamu harus menanganinya manual.
Saat frontend dan backend berbeda origin, browser bisa memblokir request karena aturan CORS. Ini bukan bug JavaScript biasa, tapi mekanisme keamanan browser.
Gejala umum CORS:
Solusinya ada di server, bukan di fetch-nya. Server perlu mengirim header CORS yang benar dan, jika perlu, menangani preflight request OPTIONS.
response.json() akan gagal kalau body bukan JSON valid. Ini sering terjadi saat:
Kalau parsing gagal, tangani seperti error data, bukan cuma error network.
Body response bersifat sekali baca. Kalau sudah dipakai oleh response.json(), kamu tidak bisa membacanya lagi sebagai text kecuali kamu clone response dulu.
const response = await fetch('/api/users');
const data = await response.json();
// response.text() di bawah ini sudah terlambatKadang developer langsung menaruh hasil fetch ke state sebelum memvalidasi bentuk datanya. Akibatnya UI bisa crash saat data tidak sesuai struktur.
Lebih aman kalau kamu cek shape minimal dulu:
const data = await response.json();
if (!Array.isArray(data)) {
throw new Error('Format data users tidak sesuai');
}loading, success, dan errorresponse.ok sebelum parse body sebagai data utamaKalau request dipakai di komponen UI, alurnya biasanya:
loading diaktifkandata diisiloading dimatikanerror diisiasync function loadProducts() {
try {
const response = await fetch('/api/products');
if (!response.ok) {
throw new Error(`Request products gagal: ${response.status
Pola ini masih sederhana, tapi sudah cukup rapi untuk debugging harian karena:
Pakai fetch kalau kamu butuh request HTTP yang ringan, native, dan cukup fleksibel untuk kerja data modern di browser. Setelah request dikirim, ingat bahwa alurnya tidak selesai saat Promise resolved. Kamu masih perlu:
response.okKalau alurnya dipahami dengan benar, debugging fetch jadi jauh lebih tenang: bukan lagi “kenapa request ini aneh?”, tapi “gagalnya ada di layer yang mana?”.