# Створення банківського додатку, частина 3: Методи отримання та використання даних ## Тест перед лекцією [Тест перед лекцією](https://ff-quizzes.netlify.app/web/quiz/45) ### Вступ У центрі кожного веб-додатку знаходяться *дані*. Дані можуть мати різні форми, але їх основна мета — показувати інформацію користувачеві. З розвитком веб-додатків, які стають все більш інтерактивними та складними, спосіб доступу користувача до інформації та взаємодії з нею стає ключовою частиною веб-розробки. У цьому уроці ми розглянемо, як асинхронно отримувати дані з сервера та використовувати ці дані для відображення інформації на веб-сторінці без перезавантаження HTML. ### Передумови Для цього уроку вам потрібно створити [Форму входу та реєстрації](../2-forms/README.md) як частину веб-додатку. Також необхідно встановити [Node.js](https://nodejs.org) і [запустити сервер API](../api/README.md) локально, щоб отримати дані облікових записів. Ви можете перевірити, чи сервер працює належним чином, виконавши цю команду в терміналі: ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## AJAX та отримання даних Традиційні веб-сайти оновлюють вміст, що відображається, коли користувач вибирає посилання або надсилає дані через форму, шляхом перезавантаження повної HTML-сторінки. Кожного разу, коли потрібно завантажити нові дані, веб-сервер повертає абсолютно нову HTML-сторінку, яку потрібно обробити браузером, перериваючи поточну дію користувача та обмежуючи взаємодії під час перезавантаження. Цей робочий процес також називається *багатосторінковим додатком* або *MPA*.  Коли веб-додатки стали більш складними та інтерактивними, з'явилася нова техніка під назвою [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Ця техніка дозволяє веб-додаткам асинхронно надсилати та отримувати дані з сервера за допомогою JavaScript, без необхідності перезавантаження HTML-сторінки, що забезпечує швидше оновлення та плавнішу взаємодію з користувачем. Коли нові дані отримуються з сервера, поточна HTML-сторінка також може бути оновлена за допомогою API [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model). З часом цей підхід еволюціонував у те, що зараз називається [*односторінковим додатком* або *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  Коли AJAX вперше був представлений, єдиним API для асинхронного отримання даних був [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Але сучасні браузери тепер також реалізують більш зручний і потужний [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), який використовує проміси та краще підходить для роботи з даними у форматі JSON. > Хоча всі сучасні браузери підтримують `Fetch API`, якщо ви хочете, щоб ваш веб-додаток працював на застарілих або старих браузерах, завжди варто перевірити [таблицю сумісності на caniuse.com](https://caniuse.com/fetch). ### Завдання У [попередньому уроці](../2-forms/README.md) ми реалізували форму реєстрації для створення облікового запису. Тепер ми додамо код для входу за допомогою існуючого облікового запису та отримання його даних. Відкрийте файл `app.js` і додайте нову функцію `login`: ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; } ``` Спочатку ми отримуємо елемент форми за допомогою `getElementById()`, а потім отримуємо ім'я користувача з введення через `loginForm.user.value`. Кожен елемент форми можна отримати за його ім'ям (встановленим у HTML за допомогою атрибута `name`) як властивість форми. Аналогічно до того, що ми зробили для реєстрації, ми створимо ще одну функцію для виконання запиту до сервера, але цього разу для отримання даних облікового запису: ```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' }; } } ``` Ми використовуємо `fetch` API для асинхронного запиту даних із сервера, але цього разу нам не потрібні додаткові параметри, окрім URL, оскільки ми лише запитуємо дані. За замовчуванням `fetch` створює HTTP-запит типу [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), що саме нам і потрібно. ✅ `encodeURIComponent()` — це функція, яка екранує спеціальні символи для URL. Які проблеми можуть виникнути, якщо ми не викличемо цю функцію і використаємо значення `user` безпосередньо в URL? Тепер оновимо нашу функцію `login`, щоб використовувати `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'); } ``` Оскільки `getAccount` є асинхронною функцією, нам потрібно використовувати ключове слово `await`, щоб дочекатися результату сервера. Як і у випадку з будь-яким запитом до сервера, ми також повинні обробляти помилки. Поки що ми просто додамо повідомлення в лог для відображення помилки, а пізніше повернемося до цього. Потім нам потрібно зберегти дані десь, щоб пізніше використовувати їх для відображення інформації на панелі управління. Оскільки змінна `account` ще не існує, ми створимо глобальну змінну для неї у верхній частині нашого файлу: ```js let account = null; ``` Після того, як дані користувача збережені у змінній, ми можемо перейти зі сторінки *login* на *dashboard* за допомогою функції `navigate()`, яку ми вже маємо. Нарешті, нам потрібно викликати нашу функцію `login`, коли форма входу надсилається, модифікувавши HTML: ```html