# Изградња банкарске апликације, део 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 (асинхрони JavaScript и XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Ова техника омогућава веб апликацијама да шаљу и преузимају податке са сервера асинхроно користећи JavaScript, без потребе за поновним учитавањем HTML странице, што резултира бржим ажурирањима и глаткијим интеракцијама корисника. Када се нови подаци добију са сервера, тренутна HTML страница може се ажурирати JavaScript-ом користећи [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. Временом, овај приступ је еволуирао у оно што се данас назива [*једностранична апликација* или *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` креира [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP захтев, што је управо оно што нам овде треба. ✅ `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