Siti sedang mencari cabang toko Budi yang paling dekat. Daftar cabang memang tersedia, tetapi tersusun alfabetis — tidak membantu bagi siapa pun yang hanya ingin tahu “yang terdekat dari posisi saya sekarang”. Browser punya jawaban untuk kebutuhan ini: Geolocation API, yang membaca posisi perangkat dari sumber seperti Wi-Fi, seluler, atau GPS, lalu menyerahkannya ke JavaScript — asalkan pengguna menyetujuinya.
Perizinan bukan pelengkap, melainkan inti desain API ini: posisi adalah data yang sensitif, sehingga setiap permintaan muncul lebih dulu sebagai dialog pilihan di tangan pengunjung. Konsekuensinya, kode kita selalu menyiapkan dua jalur: callback sukses yang menerima posisi, dan callback galat yang menerima penolakan maupun kegagalan pengukuran.
Meminta Posisi dengan getCurrentPosition #
Aturannya: navigator.geolocation.getCurrentPosition(sukses, galat, opsi) meminta satu kali pembacaan posisi. Kedua callback wajib disiapkan; opsi ketiga bersifat pilihan. Karena prosesnya butuh waktu — dialog harus dijawab, sumber posisi harus dikonsultasi — hasilnya dikirim lewat callback, bukan sebagai nilai kembali:
// posisi-pengguna.js — membaca posisi perangkat dengan izin pengguna
// Geolocation API hanya ada di browser;
// berkas ini lolos node --check dan dijalankan pada halaman toko.
const tombolCari = document.querySelector("#cari-toko");
const panelHasil = document.querySelector("#hasil-toko");
tombolCari.addEventListener("click", () => {
panelHasil.textContent = "Mencari posisi...";
navigator.geolocation.getCurrentPosition(
// callback sukses: object GeolocationPosition
(posisi) => {
const { latitude, longitude } = posisi.coords;
console.log(`Posisi: ${latitude.toFixed(4)}, ${longitude.toFixed(4)}`);
panelHasil.textContent = "Toko terdekat: Cabang Semporna (2,1 km)";
},
// callback galat: object GeolocationPositionError
(error) => {
console.log("Gagal, kode:", error.code, "-", error.message);
panelHasil.textContent = "Posisi tidak tersedia. Pilih toko secara manual.";
},
{ timeout: 8000, maximumAge: 60000, enableHighAccuracy: false }
);
});Geolocation API tidak tersedia di Node maupun jsdom, sehingga berkas ini diverifikasi sintaksnya dengan node --check posisi-pengguna.js; keluaran berikut dicatat sebagai keluaran console browser sesuai perilaku standar. Ketika Siti menekan tombol dan menyetujui dialog izin, console mencatat:
Keluaran console browser:
Posisi: -6.2146, 106.8451Mari kita telaah baris-baris pentingnya:
- Baris 8 (
addEventListener("click", ...)): permintaan posisi dikaitkan dengan aksi pengunjung — tombol “Cari toko terdekat”. Browser menampilkan dialog izin pada saat itu, dan teks tombol sekaligus menjelaskan mengapa posisi diminta. - Baris 11 (
getCurrentPosition(...)): permintaan dikirim ke browser. Tidak ada nilai posisi yang dikembalikan langsung; kedua callback di baris berikutnya yang menerima hasilnya. - Baris 13–17 (callback sukses): parameter
posisiberupa objectGeolocationPosition. Properticoordsmemuatlatitude,longitude,accuracy(akurasi dalam meter), dan — bila tersedia —altitude,heading, sertaspeed.toFixed(4)membulatkan koordinat untuk tampilan. - Baris 19–22 (callback galat): parameter
errorberupaGeolocationPositionErrordengancodedanmessage. Panel tidak dibiarkan kosong — pesan “pilih toko secara manual” memberi jalur lanjutan bagi pengunjung yang menolak. - Baris 23 (object opsi):
timeout: 8000membatasi penantian delapan detik,maximumAge: 60000menerima posisi cache hingga usia satu menit, danenableHighAccuracy: falsememilih sumber yang hemat energi untuk kebutuhan “toko terdekat”.
Callback Galat dan Kode Kesalahannya #
Tiga kode galat resmi menutup semua jalur kegagalan, dan masing-masing menuntut reaksi yang berbeda:
| Kode | Nama | Penyebab khas |
|---|---|---|
1 | PERMISSION_DENIED | pengunjung menolak dialog izin, atau izin sudah berstatus ditolak |
2 | POSITION_UNAVAILABLE | perangkat tidak bisa menentukan posisi — sumber tidak ada atau sinyal tidak memadai |
3 | TIMEOUT | batas options.timeout terlampaui sebelum posisi diperoleh |
Teks error.message berbeda-beda antar browser dan berubah-ubah antar versi, jadi jadikan error.code acuan keputusan dan error.message hanya sebagai catatan di console. Untuk PERMISSION_DENIED, UI yang baik tidak mengulang permintaan secara paksa — pengunjung sudah berbicara; tawarkan pilihan manual seperti yang ditulis panel pada contoh. Untuk TIMEOUT, pemanggilan ulang dengan enableHighAccuracy: false sering berhasil karena sumber yang lebih cepat dipilih. Dengan izin yang ditolak, keluaran console pada contoh di atas berubah menjadi:
Keluaran console browser:
Gagal, kode: 1 - User denied GeolocationOpsi Pencarian dan watchPosition #
Object opsi menyeimbangkan kecepatan, akurasi, dan konsumsi daya:
| Opsi | Arti | Nilai default |
|---|---|---|
timeout | batas waktu tunggu posisi, dalam milidetik | tak terbatas |
maximumAge | usia maksimum posisi cache yang masih boleh dipakai, dalam milidetik | 0 (selalu posisi baru) |
enableHighAccuracy | memilih sumber paling akurat (misalnya GPS) — lebih teliti tetapi lebih lambat dan lebih haus daya | false |
Kombinasi yang lazim: maximumAge besar untuk fitur yang tidak butuh ketelitian tinggi (posisi cache dijawab nyaris seketika), dan timeout wajar seperti 8–10 detik agar UI tidak menunggu tanpa batas. Permintaan pertama dengan maximumAge: 60000 bisa terjawab dari cache tanpa dialog tambahan, asalkan posisi pernah dibaca dalam satu menit terakhir.
Untuk fitur yang mengikuti pergerakan — melacak kurir yang sedang mengantar paket, misalnya — tersedia watchPosition(sukses, galat, opsi) dengan bentuk argumen yang sama persis. Perbedaannya pada perilaku: callback sukses dipanggil ulang setiap kali posisi berubah, dan nilai kembalian berupa angka id yang digunakan clearWatch(id) untuk menghentikan pelacakan. Aturan privasinya tidak berubah: API ini hanya aktif pada secure context (HTTPS atau localhost), dan callback pelacakan yang tidak dihentikan akan terus mengirim posisi selama tab terbuka — selalu simpan id-nya dan panggil clearWatch saat fitur ditutup.
Dengan callback sukses, callback galat, dan tiga opsi pencarian, pemakaian Geolocation API sudah lengkap untuk kasus “toko terdekat” — dan pola dua-jalur ini berulang lagi pada API berizin lainnya yang kita rangkum di chapter berikutnya.
Berkas Sumber
Berkas pendukung halaman ini dapat diunduh dan dijalankan langsung sesuai penjelasan di atas.
posisi-pengguna.js
Unduh berkas// posisi-pengguna.js — membaca posisi perangkat dengan izin pengguna
// Geolocation API hanya ada di browser;
// berkas ini lolos node --check dan dijalankan pada halaman toko.
const tombolCari = document.querySelector("#cari-toko");
const panelHasil = document.querySelector("#hasil-toko");
tombolCari.addEventListener("click", () => {
panelHasil.textContent = "Mencari posisi...";
navigator.geolocation.getCurrentPosition(
// callback sukses: object GeolocationPosition
(posisi) => {
const { latitude, longitude } = posisi.coords;
console.log(`Posisi: ${latitude.toFixed(4)}, ${longitude.toFixed(4)}`);
panelHasil.textContent = "Toko terdekat: Cabang Semporna (2,1 km)";
},
// callback galat: object GeolocationPositionError
(error) => {
console.log("Gagal, kode:", error.code, "-", error.message);
panelHasil.textContent = "Posisi tidak tersedia. Pilih toko secara manual.";
},
{ timeout: 8000, maximumAge: 60000, enableHighAccuracy: false }
);
});