# Membangun Aplikasi Perbankan Bagian 3: Metode Mengambil dan Menggunakan Data ## Kuis Pra-Pelajaran [Kuis pra-pelajaran](https://ff-quizzes.netlify.app/web/quiz/45) ### Pendahuluan Di inti setiap aplikasi web terdapat *data*. Data dapat berbentuk berbagai macam, tetapi tujuan utamanya selalu untuk menampilkan informasi kepada pengguna. Dengan aplikasi web yang semakin interaktif dan kompleks, bagaimana pengguna mengakses dan berinteraksi dengan informasi kini menjadi bagian penting dari pengembangan web. Dalam pelajaran ini, kita akan melihat cara mengambil data dari server secara asinkron, dan menggunakan data ini untuk menampilkan informasi di halaman web tanpa memuat ulang HTML. ### Prasyarat Anda perlu telah membangun bagian [Formulir Login dan Registrasi](../2-forms/README.md) dari aplikasi web untuk pelajaran ini. Anda juga perlu menginstal [Node.js](https://nodejs.org) dan [menjalankan server API](../api/README.md) secara lokal agar Anda mendapatkan data akun. Anda dapat menguji apakah server berjalan dengan benar dengan menjalankan perintah ini di terminal: ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## AJAX dan Pengambilan Data Situs web tradisional memperbarui konten yang ditampilkan ketika pengguna memilih tautan atau mengirimkan data menggunakan formulir, dengan memuat ulang seluruh halaman HTML. Setiap kali data baru perlu dimuat, server web mengembalikan halaman HTML baru yang harus diproses oleh browser, mengganggu tindakan pengguna saat ini dan membatasi interaksi selama pemuatan ulang. Alur kerja ini juga disebut sebagai *Multi-Page Application* atau *MPA*.  Ketika aplikasi web mulai menjadi lebih kompleks dan interaktif, muncul teknik baru yang disebut [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Teknik ini memungkinkan aplikasi web untuk mengirim dan mengambil data dari server secara asinkron menggunakan JavaScript, tanpa harus memuat ulang halaman HTML, menghasilkan pembaruan yang lebih cepat dan interaksi pengguna yang lebih mulus. Ketika data baru diterima dari server, halaman HTML saat ini juga dapat diperbarui dengan JavaScript menggunakan API [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model). Seiring waktu, pendekatan ini berkembang menjadi apa yang sekarang disebut [*Single-Page Application* atau *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  Ketika AJAX pertama kali diperkenalkan, satu-satunya API yang tersedia untuk mengambil data secara asinkron adalah [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Namun, browser modern sekarang juga mengimplementasikan [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API) yang lebih nyaman dan kuat, menggunakan promises dan lebih cocok untuk memanipulasi data JSON. > Meskipun semua browser modern mendukung `Fetch API`, jika Anda ingin aplikasi web Anda bekerja di browser lama atau lawas, selalu merupakan ide yang baik untuk memeriksa [tabel kompatibilitas di caniuse.com](https://caniuse.com/fetch) terlebih dahulu. ### Tugas Dalam [pelajaran sebelumnya](../2-forms/README.md) kita telah mengimplementasikan formulir registrasi untuk membuat akun. Sekarang kita akan menambahkan kode untuk login menggunakan akun yang sudah ada, dan mengambil datanya. Buka file `app.js` dan tambahkan fungsi `login` baru: ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; } ``` Di sini kita mulai dengan mengambil elemen formulir menggunakan `getElementById()`, lalu kita mendapatkan nama pengguna dari input dengan `loginForm.user.value`. Setiap kontrol formulir dapat diakses berdasarkan namanya (diatur di HTML menggunakan atribut `name`) sebagai properti dari formulir. Dengan cara yang mirip dengan apa yang kita lakukan untuk registrasi, kita akan membuat fungsi lain untuk melakukan permintaan server, tetapi kali ini untuk mengambil data akun: ```js 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' }; } } ``` Kita menggunakan `fetch` API untuk meminta data secara asinkron dari server, tetapi kali ini kita tidak memerlukan parameter tambahan selain URL yang akan dipanggil, karena kita hanya mengambil data. Secara default, `fetch` membuat permintaan HTTP [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), yang sesuai dengan kebutuhan kita di sini. ✅ `encodeURIComponent()` adalah fungsi yang menghindari karakter khusus untuk URL. Masalah apa yang mungkin terjadi jika kita tidak memanggil fungsi ini dan langsung menggunakan nilai `user` dalam URL? Sekarang mari kita perbarui fungsi `login` kita untuk menggunakan `getAccount`: ```js 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'); } ``` Pertama, karena `getAccount` adalah fungsi asinkron, kita perlu mencocokkannya dengan kata kunci `await` untuk menunggu hasil server. Seperti halnya permintaan server, kita juga harus menangani kasus kesalahan. Untuk saat ini kita hanya akan menambahkan pesan log untuk menampilkan kesalahan, dan kembali ke sana nanti. Kemudian kita harus menyimpan data di suatu tempat agar kita dapat menggunakannya nanti untuk menampilkan informasi dashboard. Karena variabel `account` belum ada, kita akan membuat variabel global untuk itu di bagian atas file kita: ```js let account = null; ``` Setelah data pengguna disimpan ke dalam variabel, kita dapat bernavigasi dari halaman *login* ke *dashboard* menggunakan fungsi `navigate()` yang sudah kita miliki. Akhirnya, kita perlu memanggil fungsi `login` kita ketika formulir login dikirimkan, dengan memodifikasi HTML: ```html