# Build a Banking App Part 3: Methods of Fetching and Using Data ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/45) ### Introduction Data is the backbone of every web application. It comes in various forms, but its primary purpose is to present information to users. As web apps grow more interactive and complex, how users access and interact with this information has become a crucial aspect of web development. In this lesson, we'll explore how to fetch data asynchronously from a server and use it to display information on a web page without reloading the HTML. ### Prerequisite Before starting this lesson, you should have completed the [Login and Registration Form](../2-forms/README.md) section of the web app. Additionally, ensure you have installed [Node.js](https://nodejs.org) and [run the server API](../api/README.md) locally to access account data. You can verify that the server is running correctly by executing the following command in a terminal: ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## AJAX and data fetching Traditional websites update their content when users click a link or submit a form by reloading the entire HTML page. Each time new data is needed, the web server sends back a fresh HTML page, which the browser processes. This interrupts the user's current action and limits interactions during the reload. This approach is known as a *Multi-Page Application* or *MPA*.  As web applications became more interactive and complex, a technique called [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)) was introduced. AJAX allows web apps to send and retrieve data from a server asynchronously using JavaScript, without reloading the HTML page. This results in faster updates and smoother user experiences. Once new data is received, JavaScript can update the current HTML page using the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. Over time, this approach evolved into what is now known as a [*Single-Page Application* or *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  Initially, the only API available for asynchronous data fetching was [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). However, modern browsers now support the more convenient and powerful [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), which uses promises and is better suited for handling JSON data. > While all modern browsers support the `Fetch API`, if you want your web application to work on older browsers, it's a good idea to check the [compatibility table on caniuse.com](https://caniuse.com/fetch) first. ### Task In [the previous lesson](../2-forms/README.md), we implemented the registration form to create an account. Now, we'll add code to log in using an existing account and fetch its data. Open the `app.js` file and add a new `login` function: ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; } ``` Here, we start by retrieving the form element using `getElementById()`. Then, we get the username from the input field using `loginForm.user.value`. Each form control can be accessed by its name (defined in the HTML using the `name` attribute) as a property of the form. Similar to the registration process, we'll create another function to send a server request, but this time to retrieve account data: ```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' }; } } ``` We use the `fetch` API to request data asynchronously from the server. This time, we don't need any extra parameters other than the URL, as we're only querying data. By default, `fetch` creates a [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP request, which is exactly what we need here. ✅ `encodeURIComponent()` is a function that escapes special characters for URLs. What problems might arise if we don't use this function and directly include the `user` value in the URL? Next, we'll update our `login` function to use `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'); } ``` Since `getAccount` is an asynchronous function, we use the `await` keyword to wait for the server's response. As with any server request, we need to handle errors. For now, we'll simply log the error message and revisit this later. After retrieving the user data, we need to store it somewhere for later use in displaying dashboard information. Since the `account` variable doesn't exist yet, we'll create a global variable for it at the top of our file: ```js let account = null; ``` Once the user data is saved in a variable, we can navigate from the *login* page to the *dashboard* using the `navigate()` function we already have. Finally, we need to call our `login` function when the login form is submitted. Update the HTML as follows: ```html