# Изградња апликације за банкарство, део 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