Cara mengatasi circular structure JSON JavaScript paling cepat adalah putus referensi melingkarnya dengan fungsi replacer di JSON.stringify(). Error TypeError: Converting circular structure to JSON muncul karena object menunjuk ke dirinya sendiri atau ke parentnya, sehingga proses serialisasi tidak pernah selesai.
Penyebab TypeError Converting Circular Structure to JSON
Object JavaScript hidup di memori dan boleh saling menunjuk. JSON string hanya format teks berurutan, tanpa konsep referensi. Ketika A menunjuk ke B lalu B menunjuk balik ke A, stringify terjebak dalam loop.
Pola yang sering memicunya adalah relasi parent-child seperti ini:
const user = { name: "Andi" };
user.profile = { owner: user };
JSON.stringify(user); // TypeError
Browser dan Node.js sama-sama melempar TypeError untuk kasus ini. Stringify memang tidak menyimpan referensi ganda karena spesifikasi JSON tidak mendukungnya.
Error/Kondisi, Penyebab, dan Solusi Cepat
Pesan lengkap biasanya berbunyi Converting circular structure to JSON --> starting at object with constructor 'Object' --- property '...' closes the circle. Nama properti di akhir pesan menunjukkan titik loopnya.
| Error/Kondisi | Penyebab | Solusi |
|---|---|---|
| Self-reference | Object menyimpan dirinya sendiri | Hapus properti atau kembalikan undefined di replacer |
| Relasi dua arah | Parent dan child saling menyimpan | Simpan id saja, bukan object penuh |
| State tercampur DOM | Menyimpan elemen atau cache besar | Pisahkan data murni sebelum stringify |
Putus referensi cocok untuk log, debug, dan simpan sementara. Ganti struktur data cocok untuk relasi yang memang perlu disimpan permanen.
Cara Memperbaiki dengan Replacer dan WeakSet
- Reproduksi error dengan
JSON.stringify(data)tanpa replacer. - Tambah fungsi replacer yang melacak object yang sudah dikunjungi.
- Jalankan ulang stringify dan periksa hasilnya dengan
JSON.parse().
const seen = new WeakSet();
const hasil = JSON.stringify(user, (key, value) => {
if (typeof value === "object" && value !== null) {
if (seen.has(value)) return undefined;
seen.add(value);
}
return value;
});
WeakSet dipilih karena tidak menahan object di memori setelah selesai. Untuk relasi dua arah yang perlu dipertahankan, alternatif yang lebih rapi:
const child = { id: 2, parentId: 1 };
const parent = { id: 1, children: [child] };
Cara Mencegah Circular Muncul Lagi
Normalisasi respons API sebelum masuk localStorage, karena localStorage hanya menerima string. Ambil field yang memang perlu ditampilkan atau dikirim balik.
- Pisahkan state UI, cache, dan elemen DOM dari data bersih.
- Buat fungsi khusus seperti
toPlainUser()untuk serialisasi. - Validasi object sebelum stringify bila datanya berasal dari banyak sumber.
FAQ
Apakah JSON.stringify bisa langsung menangani circular?
Tidak, stringify melempar TypeError dan membutuhkan replacer atau struktur data yang diperbaiki.
Bagaimana menyimpan object berelasi ke localStorage?
Simpan versi plain berisi id dan field penting, lalu gabungkan kembali setelah JSON.parse().
Kapan memakai replacer custom dan kapan ubah struktur data?
Pakai replacer untuk debug dan log cepat, ubah struktur data bila relasi perlu disimpan dan dibaca ulang.