Vue · Bab 5
CRUD dan Penanganan Galat
Menyimpan, mengubah, dan menghapus data lewat API dengan POST, PUT, dan DELETE, membaca arti status 201, 204, 404, dan 422, menampilkan pesan 422 per field, dan menyatukan penanganan galat dalam satu fungsi.
Bab 4 hanya membaca data. Aplikasi pengelola, misalnya halaman petugas Perpustakaan Pelita yang menambah buku baru, juga menulis: membuat, mengubah, dan menghapus. Setiap tulisan bisa ditolak server, jadi bab ini sama banyaknya tentang galat seperti tentang CRUD.
5.1 POST: Membuat Data Baru
http.post(url, data) mengirim objek sebagai body JSON. Server yang berhasil membuat data menjawab 201 Created dan mengembalikan data baru itu, lengkap dengan id yang dibuat server.
🧪 Coba ubah: klik dua kali. Id bertambah karena server yang memberi id, bukan kode di halaman. Lalu Jalankan ulang: server tiruan kembali ke tujuh buku.
Belum ada output.
5.2 Galat 422: Pesan per Field
Bila isian tidak lolos validasi, Laravel menjawab 422 Unprocessable Content dengan body seperti ini:
{
message: 'The judul field is required. (and 1 more error)',
errors: {
judul: ['The judul field is required.'],
tahun: ['The tahun field must be an integer.'],
},
}
errors berisi daftar pesan per field; biasanya cukup pesan pertama. Pesan itu ditaruh tepat di bawah input-nya, dan input ditandai aria-invalid="true" serta dihubungkan ke pesannya dengan aria-describedby, sehingga pembaca layar membacakan keduanya bersama.
🧪 Coba ubah: klik Simpan dengan form kosong, lalu isi judul saja. Pesan judul hilang, pesan tahun tetap.
Belum ada output.
5.3 Galat 404: Pesanmu Sendiri
http.get('/buku/99') menjawab 404. Body-nya punya message, tetapi pesan itu ditulis untuk pemrogram dan bisa berubah kapan saja. Tampilkan kalimatmu sendiri, misalnya “Buku tidak ditemukan”, dan pilih kalimat itu berdasarkan status, bukan isi message.
🧪 Coba ubah: ganti 99 menjadi 3 untuk melihat jalur berhasil.
Belum ada output.
5.4 PUT dan DELETE
Server contoh bab ini hanya menyediakan tiga endpoint, jadi PUT dan DELETE ditunjukkan sebagai potongan kode. Keduanya kamu latih di lab dengan API Smart Retail.
// PUT mengganti data: kirim SEMUA field, bukan hanya yang berubah.
const lama = koleksi.value[0];
const r = await http.put('/buku/' + lama.id, { judul: lama.judul, penulis: lama.penulis, tahun: 2006 });
Object.assign(lama, r.data.data);
// DELETE: 204 No Content, tanpa body. Jangan membaca r.data.data.
await http.delete('/buku/' + lama.id);
koleksi.value = koleksi.value.filter((b) => b.id !== lama.id);
| Status | Arti | Yang dilakukan frontend |
|---|---|---|
| 200 | berhasil, ada body | pakai r.data.data |
| 201 | data baru dibuat | tambahkan r.data.data ke daftar |
| 204 | berhasil, tanpa body | ubah daftar sendiri |
| 404 | data tidak ada | pesan “tidak ditemukan” |
| 422 | isian ditolak | pesan per field dari errors |
5.5 Satu Fungsi untuk Semua Galat
Menulis if (e.response && e.response.status === …) di setiap catch cepat menjadi berantakan. Satukan dalam satu fungsi yang mengubah galat axios menjadi bentuk yang selalu sama: { status, pesan, field }.
🧪 Coba ubah: tambahkan galat buatan { response: { status: 422, data: { errors: { judul: ['Wajib diisi'] } } } } ke contoh dan tampilkan field-nya.
Belum ada output.
Status 0 bukan status HTTP; itu kesepakatan kita untuk “tidak ada respons sama sekali” (server mati atau jaringan putus).
5.6 Interceptor Respons
Interceptor adalah fungsi yang dilewati setiap respons sebelum sampai ke kodemu. Dengan interceptor, setiap galat sudah dinormalisasi:
http.interceptors.response.use(
(r) => r,
(e) => Promise.reject(normalisasiGalat(e)),
);
// di mana saja: catch (g) { pesanUmum.value = g.pesan; }
Keuntungannya: satu tempat, tidak ada catch yang lupa. Jebakannya: yang ditangkap catch bukan lagi galat axios. g.response tidak ada; yang ada g.status. Seluruh tim harus tahu bentuk baru ini, dan bab 8 akan memakai interceptor yang sama untuk menangani 401.
5.7 Fitur yang Sama Tiga Kali
Fitur “simpan data baru dengan validasi” sudah kamu temui tiga kali: di Blade (Laravel Lab 3), di REST API (Lab 9), dan sekarang di Vue.
| Pertanyaan | Blade | REST API | Vue + API |
|---|---|---|---|
| Siapa merender HTML? | server | tidak ada HTML | browser (Vue) |
| Di mana validasi berjalan? | server | server | server; klien boleh menambah cek cepat |
| Bagaimana galat ditampilkan? | redirect + $errors | JSON 422 | errors dari JSON, dirender Vue |
| Bila server mati? | halaman tidak terbuka | request gagal | halaman tetap ada, tampilkan galat jaringan |
Validasi di klien hanya kenyamanan; server tetap penentu, karena siapa pun bisa mengirim request tanpa melewati form-mu.
Rangkuman
- POST → 201 + data baru; PUT mengirim semua field; DELETE → 204 tanpa body.
- 422 membawa
errorsper field: pesan pertama di bawah input,aria-invalid+aria-describedby. - Pesan untuk pengguna dipilih dari status, bukan dari
messageserver. normalisasiGalat(e)→{ status, pesan, field }; interceptor bisa memanggilnya untuk semua respons.
Berikutnya: Lab bab 5 mengelola produk Smart Retail: normalisasiGalat, POST, pesan 422 per field, dan PUT.