# 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 At the heart of every web application lies *data*. Data can take various forms, but its primary purpose is to present information to the user. As web apps become more interactive and complex, how users access and interact with this information has become a critical aspect of web development. In this lesson, we’ll explore how to fetch data from a server asynchronously 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, you need to install [Node.js](https://nodejs.org) and [run the server API](../api/README.md) locally to access account data. To verify that the server is running correctly, execute 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 the displayed content when a user clicks a link or submits a form by reloading the entire HTML page. Each time new data is needed, the web server sends back a completely new HTML page, which the browser processes. This interrupts the user’s current action and limits interactions during the reload. This workflow is known as a *Multi-Page Application* or *MPA*.  As web applications became more complex and interactive, a new 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 interactions. Once new data is received from the server, the current HTML page can be updated using JavaScript and the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. Over time, this approach evolved into what we now call a [*Single-Page Application* or *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  When AJAX was first introduced, the only available API for fetching data asynchronously was [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Modern browsers, however, 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 app 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()`, and then we get the username from the input field using `loginForm.user.value`. Each form control can be accessed by its name (set in the HTML using the `name` attribute) as a property of the form. Similar to what we did for registration, we’ll create another function to perform 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 additional 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, let’s 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 also need to handle errors. For now, we’ll simply log the error message and revisit this later. We then need to store the data somewhere so we can use it to display information on the dashboard. 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. Modify the HTML as follows: ```html