# Membangun Aplikasi Perbankan Bagian 3: Metode Mengambil dan Menggunakan Data Bayangkan komputer Enterprise di Star Trek - ketika Kapten Picard meminta status kapal, informasi muncul seketika tanpa seluruh antarmuka mati dan dibangun ulang. Aliran informasi yang mulus itulah yang sedang kita bangun di sini dengan pengambilan data yang dinamis. Saat ini, aplikasi perbankan Anda seperti koran cetak - informatif tetapi statis. Kita akan mengubahnya menjadi sesuatu yang lebih mirip pusat kendali di NASA, di mana data mengalir terus-menerus dan diperbarui secara real-time tanpa mengganggu alur kerja pengguna. Anda akan belajar cara berkomunikasi dengan server secara asinkron, menangani data yang tiba di waktu yang berbeda, dan mengubah informasi mentah menjadi sesuatu yang bermakna bagi pengguna Anda. Ini adalah perbedaan antara demo dan perangkat lunak yang siap produksi. ## Kuis Pra-Kuliah [Kuis pra-kuliah](https://ff-quizzes.netlify.app/web/quiz/45) ### Prasyarat Sebelum mendalami pengambilan data, pastikan Anda memiliki komponen berikut: - **Pelajaran Sebelumnya**: Selesaikan [Formulir Login dan Registrasi](../2-forms/README.md) - kita akan membangun di atas dasar ini - **Server Lokal**: Instal [Node.js](https://nodejs.org) dan [jalankan API server](../api/README.md) untuk menyediakan data akun - **Koneksi API**: Uji koneksi server Anda dengan perintah ini: ```bash curl http://localhost:5000/api # Expected response: "Bank API v1.0.0" ``` Tes cepat ini memastikan semua komponen berkomunikasi dengan baik: - Memverifikasi bahwa Node.js berjalan dengan benar di sistem Anda - Mengonfirmasi bahwa server API Anda aktif dan merespons - Memvalidasi bahwa aplikasi Anda dapat terhubung ke server (seperti memeriksa kontak radio sebelum misi) --- ## Memahami Pengambilan Data di Aplikasi Web Modern Cara aplikasi web menangani data telah berkembang pesat selama dua dekade terakhir. Memahami evolusi ini akan membantu Anda menghargai mengapa teknik modern seperti AJAX dan Fetch API sangat kuat dan mengapa mereka menjadi alat penting bagi pengembang web. Mari kita jelajahi bagaimana situs web tradisional bekerja dibandingkan dengan aplikasi dinamis dan responsif yang kita bangun saat ini. ### Aplikasi Multi-Halaman Tradisional (MPA) Di masa awal web, setiap klik seperti mengganti saluran di televisi lama - layar akan kosong, lalu perlahan-lahan menampilkan konten baru. Inilah kenyataan aplikasi web awal, di mana setiap interaksi berarti membangun ulang seluruh halaman dari awal. ```mermaid sequenceDiagram participant User participant Browser participant Server User->>Browser: Clicks link or submits form Browser->>Server: Requests new HTML page Note over Browser: Page goes blank Server->>Browser: Returns complete HTML page Browser->>User: Displays new page (flash/reload) ``` ![Alur pembaruan dalam aplikasi multi-halaman](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.id.png) **Mengapa pendekatan ini terasa kaku:** - Setiap klik berarti membangun ulang seluruh halaman dari awal - Pengguna terganggu di tengah-tengah aktivitas oleh kilatan halaman yang mengganggu - Koneksi internet Anda bekerja lebih keras untuk mengunduh header dan footer yang sama berulang kali - Aplikasi terasa lebih seperti membuka lemari arsip daripada menggunakan perangkat lunak ### Aplikasi Satu Halaman Modern (SPA) AJAX (Asynchronous JavaScript and XML) mengubah paradigma ini sepenuhnya. Seperti desain modular Stasiun Luar Angkasa Internasional, di mana astronot dapat mengganti komponen individual tanpa membangun ulang seluruh struktur, AJAX memungkinkan kita memperbarui bagian tertentu dari halaman web tanpa memuat ulang semuanya. Meskipun namanya menyebutkan XML, kita lebih sering menggunakan JSON saat ini, tetapi prinsip dasarnya tetap sama: memperbarui hanya apa yang perlu diubah. ```mermaid sequenceDiagram participant User participant Browser participant JavaScript participant Server User->>Browser: Interacts with page Browser->>JavaScript: Triggers event handler JavaScript->>Server: Fetches only needed data Server->>JavaScript: Returns JSON data JavaScript->>Browser: Updates specific page elements Browser->>User: Shows updated content (no reload) ``` ![Alur pembaruan dalam aplikasi satu halaman](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.id.png) **Mengapa SPA terasa jauh lebih baik:** - Hanya bagian yang benar-benar berubah yang diperbarui (cerdas, bukan?) - Tidak ada lagi gangguan yang mengganggu - pengguna tetap fokus - Lebih sedikit data yang dikirim berarti waktu pemuatan lebih cepat - Semuanya terasa cepat dan responsif, seperti aplikasi di ponsel Anda ### Evolusi ke Fetch API Modern Browser modern menyediakan [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), yang menggantikan [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest) yang lebih lama. Seperti perbedaan antara mengoperasikan telegraf dan menggunakan email, Fetch API menggunakan promises untuk kode asinkron yang lebih bersih dan secara alami menangani JSON. | Fitur | XMLHttpRequest | Fetch API | |-------|----------------|-----------| | **Sintaks** | Berbasis callback yang kompleks | Berbasis promise yang bersih | | **Penanganan JSON** | Memerlukan parsing manual | Metode bawaan `.json()` | | **Penanganan Error** | Informasi error terbatas | Detail error yang komprehensif | | **Dukungan Modern** | Kompatibilitas legacy | ES6+ promises dan async/await | > 💡 **Kompatibilitas Browser**: Kabar baik - Fetch API bekerja di semua browser modern! Jika Anda penasaran dengan versi spesifik, [caniuse.com](https://caniuse.com/fetch) memiliki cerita kompatibilitas lengkap. > **Intinya:** - Bekerja dengan baik di Chrome, Firefox, Safari, dan Edge (pada dasarnya di mana pun pengguna Anda berada) - Hanya Internet Explorer yang membutuhkan bantuan tambahan (dan sejujurnya, sudah saatnya kita melupakan IE) - Mempersiapkan Anda dengan sempurna untuk pola async/await yang elegan yang akan kita gunakan nanti ### Mengimplementasikan Login Pengguna dan Pengambilan Data Sekarang mari kita implementasikan sistem login yang mengubah aplikasi perbankan Anda dari tampilan statis menjadi aplikasi yang fungsional. Seperti protokol autentikasi yang digunakan di fasilitas militer yang aman, kita akan memverifikasi kredensial pengguna dan kemudian memberikan akses ke data spesifik mereka. Kita akan membangun ini secara bertahap, dimulai dengan autentikasi dasar dan kemudian menambahkan kemampuan pengambilan data. #### Langkah 1: Membuat Dasar Fungsi Login Buka file `app.js` Anda dan tambahkan fungsi `login` baru. Fungsi ini akan menangani proses autentikasi pengguna: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **Mari kita uraikan:** - Kata kunci `async`? Itu memberi tahu JavaScript "hei, fungsi ini mungkin perlu menunggu sesuatu" - Kita mengambil formulir dari halaman (tidak ada yang mewah, hanya menemukannya berdasarkan ID-nya) - Kemudian kita mengambil apa pun yang diketik pengguna sebagai nama pengguna mereka - Trik yang rapi: Anda dapat mengakses input formulir apa pun dengan atribut `name` - tidak perlu panggilan getElementById tambahan! > 💡 **Pola Akses Formulir**: Setiap kontrol formulir dapat diakses berdasarkan nama (ditetapkan di HTML menggunakan atribut `name`) sebagai properti elemen formulir. Ini memberikan cara yang bersih dan mudah dibaca untuk mendapatkan data formulir. #### Langkah 2: Membuat Fungsi Pengambilan Data Akun Selanjutnya, kita akan membuat fungsi khusus untuk mengambil data akun dari server. Ini mengikuti pola yang sama seperti fungsi registrasi Anda tetapi berfokus pada pengambilan data: ```javascript async function getAccount(user) { try { const response = await fetch('//localhost:5000/api/accounts/' + encodeURIComponent(user)); return await response.json(); } catch (error) { return { error: error.message || 'Unknown error' }; } } ``` **Inilah yang dicapai oleh kode ini:** - **Menggunakan** API `fetch` modern untuk meminta data secara asinkron - **Membangun** URL permintaan GET dengan parameter nama pengguna - **Menerapkan** `encodeURIComponent()` untuk menangani karakter khusus dalam URL dengan aman - **Mengonversi** respons ke format JSON untuk manipulasi data yang mudah - **Menangani** error dengan baik dengan mengembalikan objek error daripada crash > ⚠️ **Catatan Keamanan**: Fungsi `encodeURIComponent()` menangani karakter khusus dalam URL. Seperti sistem pengkodean yang digunakan dalam komunikasi angkatan laut, ini memastikan pesan Anda tiba persis seperti yang dimaksudkan, mencegah karakter seperti "#" atau "&" disalahartikan. > **Mengapa ini penting:** - Mencegah karakter khusus merusak URL - Melindungi dari serangan manipulasi URL - Memastikan server Anda menerima data yang dimaksudkan - Mengikuti praktik pengkodean yang aman #### Memahami Permintaan HTTP GET Ada sesuatu yang mungkin mengejutkan Anda: ketika Anda menggunakan `fetch` tanpa opsi tambahan, itu secara otomatis membuat permintaan [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET). Ini sempurna untuk apa yang kita lakukan - meminta server "hei, bisakah saya melihat data akun pengguna ini?" Pikirkan permintaan GET seperti dengan sopan meminta meminjam buku dari perpustakaan - Anda meminta untuk melihat sesuatu yang sudah ada. Permintaan POST (yang kita gunakan untuk registrasi) lebih seperti menyerahkan buku baru untuk ditambahkan ke koleksi. | Permintaan GET | Permintaan POST | |----------------|-----------------| | **Tujuan** | Mengambil data yang ada | Mengirim data baru ke server | | **Parameter** | Dalam path/query string URL | Dalam body permintaan | | **Caching** | Dapat di-cache oleh browser | Tidak biasanya di-cache | | **Keamanan** | Terlihat di URL/log | Tersembunyi di body permintaan | #### Langkah 3: Menggabungkan Semuanya Sekarang bagian yang memuaskan - mari kita hubungkan fungsi pengambilan akun Anda ke proses login. Di sinilah semuanya terhubung: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; const data = await getAccount(user); if (data.error) { return console.log('loginError', data.error); } account = data; navigate('/dashboard'); } ``` Fungsi ini mengikuti urutan yang jelas: - Mengambil nama pengguna dari input formulir - Meminta data akun pengguna dari server - Menangani error yang terjadi selama proses - Menyimpan data akun dan menavigasi ke dashboard setelah berhasil > 🎯 **Pola Async/Await**: Karena `getAccount` adalah fungsi asinkron, kita menggunakan kata kunci `await` untuk menghentikan eksekusi hingga server merespons. Ini mencegah kode melanjutkan dengan data yang tidak terdefinisi. #### Langkah 4: Membuat Tempat untuk Data Anda Aplikasi Anda membutuhkan tempat untuk menyimpan informasi akun setelah dimuat. Pikirkan ini seperti memori jangka pendek aplikasi Anda - tempat untuk menyimpan data pengguna saat ini. Tambahkan baris ini di bagian atas file `app.js` Anda: ```javascript // This holds the current user's account data let account = null; ``` **Mengapa kita membutuhkan ini:** - Menyimpan data akun agar dapat diakses dari mana saja di aplikasi Anda - Memulai dengan `null` berarti "belum ada yang login" - Diperbarui ketika seseorang berhasil login atau registrasi - Bertindak seperti sumber kebenaran tunggal - tidak ada kebingungan tentang siapa yang login #### Langkah 5: Menghubungkan Formulir Anda Sekarang mari kita hubungkan fungsi login baru Anda ke formulir HTML Anda. Perbarui tag formulir Anda seperti ini: ```html
``` **Apa yang dilakukan perubahan kecil ini:** - Menghentikan formulir dari perilaku default "memuat ulang seluruh halaman" - Memanggil fungsi JavaScript khusus Anda sebagai gantinya - Menjaga semuanya tetap mulus dan seperti aplikasi satu halaman - Memberikan Anda kontrol penuh atas apa yang terjadi ketika pengguna menekan "Login" #### Langkah 6: Tingkatkan Fungsi Registrasi Anda Untuk konsistensi, perbarui fungsi `register` Anda agar juga menyimpan data akun dan menavigasi ke dashboard: ```javascript // Add these lines at the end of your register function account = result; navigate('/dashboard'); ``` **Peningkatan ini memberikan:** - Transisi **mulus** dari registrasi ke dashboard - Pengalaman pengguna **konsisten** antara alur login dan registrasi - Akses **langsung** ke data akun setelah registrasi berhasil #### Menguji Implementasi Anda ```mermaid flowchart TD A[User enters credentials] --> B[Login function called] B --> C[Fetch account data from server] C --> D{Data received successfully?} D -->|Yes| E[Store account data globally] D -->|No| F[Display error message] E --> G[Navigate to dashboard] F --> H[User stays on login page] ``` **Saatnya mencoba:** 1. Buat akun baru untuk memastikan semuanya berjalan dengan baik 2. Coba login dengan kredensial yang sama 3. Lihat konsol browser Anda (F12) jika ada yang tidak beres 4. Pastikan Anda mendarat di dashboard setelah login berhasil Jika ada yang tidak berfungsi, jangan panik! Sebagian besar masalah adalah perbaikan sederhana seperti kesalahan ketik atau lupa untuk memulai server API. #### Sepatah Kata Tentang Keajaiban Cross-Origin Anda mungkin bertanya-tanya: "Bagaimana aplikasi web saya berbicara dengan server API ini ketika mereka berjalan di port yang berbeda?" Pertanyaan yang bagus! Ini menyentuh sesuatu yang setiap pengembang web akan temui pada akhirnya. > 🔒 **Keamanan Cross-Origin**: Browser menerapkan "kebijakan asal yang sama" untuk mencegah komunikasi yang tidak sah antara domain yang berbeda. Seperti sistem pemeriksaan di Pentagon, mereka memverifikasi bahwa komunikasi diizinkan sebelum memungkinkan transfer data. > **Dalam pengaturan kita:** - Aplikasi web Anda berjalan di `localhost:3000` (server pengembangan) - Server API Anda berjalan di `localhost:5000` (server backend) - Server API menyertakan header [CORS](https://developer.mozilla.org/docs/Web/HTTP/CORS) yang secara eksplisit mengizinkan komunikasi dari aplikasi web Anda Konfigurasi ini mencerminkan pengembangan dunia nyata di mana aplikasi frontend dan backend biasanya berjalan di server terpisah. > 📚 **Pelajari Lebih Lanjut**: Pelajari lebih dalam tentang API dan pengambilan data dengan modul [Microsoft Learn tentang API](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Menghidupkan Data Anda di HTML Sekarang kita akan membuat data yang diambil terlihat oleh pengguna melalui manipulasi DOM. Seperti proses mengembangkan foto di ruang gelap, kita mengambil data yang tidak terlihat dan merendernya menjadi sesuatu yang dapat dilihat dan berinteraksi oleh pengguna. Manipulasi DOM adalah teknik yang mengubah halaman web statis menjadi aplikasi dinamis yang memperbarui kontennya berdasarkan interaksi pengguna dan respons server. ### Memilih Alat yang Tepat untuk Pekerjaan Ketika datang untuk memperbarui HTML Anda dengan JavaScript, Anda memiliki beberapa opsi. Pikirkan ini seperti alat yang berbeda dalam kotak alat - masing-masing sempurna untuk pekerjaan tertentu: | Metode | Apa yang bagus untuk | Kapan digunakan | Tingkat keamanan | |--------|-----------------------|-----------------|------------------| | `textContent` | Menampilkan data pengguna dengan aman | Kapan saja Anda menampilkan teks | ✅ Sangat aman | | `createElement()` + `append()` | Membangun tata letak yang kompleks | Membuat bagian/daftar baru | ✅ Sangat aman | | `innerHTML` | Menetapkan konten HTML | ⚠️ Usahakan untuk menghindari yang ini | ❌ Berisiko tinggi | #### Cara Aman Menampilkan Teks: textContent Properti [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) adalah teman terbaik Anda saat menampilkan data pengguna. Ini seperti memiliki penjaga keamanan untuk halaman web Anda - tidak ada yang berbahaya yang bisa masuk: ```javascript // The safe, reliable way to update text const balanceElement = document.getElementById('balance'); balanceElement.textContent = account.balance; ``` **Manfaat textContent:** - Memperlakukan semuanya sebagai teks biasa (mencegah eksekusi skrip) - Secara otomatis membersihkan konten yang ada - Efisien untuk pembaruan teks sederhana - Memberikan keamanan bawaan terhadap konten berbahaya #### Membuat Elemen HTML Dinamis Untuk konten yang lebih kompleks, gabungkan [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) dengan metode [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append): ```javascript // Safe way to create new elements const transactionItem = document.createElement('div'); transactionItem.className = 'transaction-item'; transactionItem.textContent = `${transaction.date}: ${transaction.description}`; container.append(transactionItem); ``` **Memahami pendekatan ini:** - **Membuat** elemen DOM baru secara programatis - **Mempertahankan** kontrol penuh atas atribut dan konten elemen - **Memungkinkan** struktur elemen yang kompleks dan bersarang - **Menjaga** keamanan dengan memisahkan struktur dari konten > ⚠️ **Pertimbangan Keamanan**: Meskipun [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) sering muncul di banyak tutorial, metode ini dapat mengeksekusi skrip yang disematkan. Seperti protokol keamanan di CERN yang mencegah eksekusi kode yang tidak sah, menggunakan `textContent` dan `createElement` adalah alternatif yang lebih aman. > **Risiko innerHTML:** - Menjalankan tag `