# Ustvarjanje bančne aplikacije, 3. del: Metode pridobivanja in uporabe podatkov ## Predhodni kviz [Predhodni kviz](https://ff-quizzes.netlify.app/web/quiz/45) ### Uvod Jedro vsake spletne aplikacije so *podatki*. Podatki lahko obstajajo v različnih oblikah, vendar je njihov glavni namen prikazovanje informacij uporabniku. Z naraščajočo interaktivnostjo in kompleksnostjo spletnih aplikacij je način, kako uporabnik dostopa do informacij in z njimi interagira, postal ključni del razvoja spletnih aplikacij. V tej lekciji bomo videli, kako asinhrono pridobiti podatke s strežnika in jih uporabiti za prikaz informacij na spletni strani, ne da bi morali ponovno naložiti HTML. ### Predpogoji Za to lekcijo morate imeti izdelan [obrazec za prijavo in registracijo](../2-forms/README.md) kot del spletne aplikacije. Prav tako morate namestiti [Node.js](https://nodejs.org) in [lokalno zagnati strežniški API](../api/README.md), da pridobite podatke o računih. Preverite, ali strežnik pravilno deluje, tako da v terminalu zaženete naslednji ukaz: ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## AJAX in pridobivanje podatkov Tradicionalne spletne strani posodabljajo prikazano vsebino, ko uporabnik izbere povezavo ali pošlje podatke prek obrazca, tako da ponovno naložijo celotno HTML stran. Vsakič, ko je treba naložiti nove podatke, spletni strežnik vrne povsem novo HTML stran, ki jo mora brskalnik obdelati, kar prekine trenutno dejanje uporabnika in omeji interakcije med nalaganjem. Ta način delovanja imenujemo *večstranska aplikacija* ali *MPA*.  Ko so spletne aplikacije postale bolj kompleksne in interaktivne, se je pojavila nova tehnika, imenovana [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Ta tehnika omogoča, da spletne aplikacije pošiljajo in pridobivajo podatke s strežnika asinhrono z uporabo JavaScripta, ne da bi bilo treba ponovno naložiti HTML stran, kar omogoča hitrejše posodobitve in bolj gladke interakcije z uporabnikom. Ko so novi podatki pridobljeni s strežnika, je mogoče trenutno HTML stran posodobiti z JavaScriptom z uporabo [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API-ja. Sčasoma se je ta pristop razvil v to, kar danes imenujemo [*enostranska aplikacija* ali *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  Ko je bil AJAX prvič predstavljen, je bil edini API za asinhrono pridobivanje podatkov [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Vendar pa sodobni brskalniki zdaj podpirajo bolj priročen in zmogljiv [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), ki uporablja obljube (promises) in je bolje prilagojen za obdelavo podatkov v obliki JSON. > Čeprav vsi sodobni brskalniki podpirajo `Fetch API`, je vedno dobro preveriti [tabelo združljivosti na caniuse.com](https://caniuse.com/fetch), če želite, da vaša spletna aplikacija deluje tudi v starejših brskalnikih. ### Naloga V [prejšnji lekciji](../2-forms/README.md) smo implementirali obrazec za registracijo za ustvarjanje računa. Zdaj bomo dodali kodo za prijavo z obstoječim računom in pridobivanje njegovih podatkov. Odprite datoteko `app.js` in dodajte novo funkcijo `login`: ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; } ``` Začnemo z iskanjem elementa obrazca z `getElementById()`, nato pa pridobimo uporabniško ime iz vnosa z `loginForm.user.value`. Vsak kontrolnik obrazca je mogoče dostopati prek njegovega imena (določenega v HTML-ju z atributom `name`) kot lastnosti obrazca. Podobno kot pri registraciji bomo ustvarili drugo funkcijo za izvedbo zahteve strežniku, tokrat za pridobivanje podatkov o računu: ```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' }; } } ``` Uporabimo `fetch` API za asinhrono zahtevo podatkov s strežnika, vendar tokrat ne potrebujemo dodatnih parametrov, razen URL-ja, saj samo poizvedujemo podatke. Privzeto `fetch` ustvari HTTP zahtevo [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), kar je točno tisto, kar potrebujemo. ✅ `encodeURIComponent()` je funkcija, ki pobegne posebne znake za URL. Kakšne težave bi lahko imeli, če te funkcije ne pokličemo in neposredno uporabimo vrednost `user` v URL-ju? Zdaj posodobimo našo funkcijo `login`, da uporabi `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'); } ``` Ker je `getAccount` asinhrona funkcija, jo moramo združiti z ključnimi besedami `await`, da počakamo na rezultat strežnika. Kot pri vsaki zahtevi strežniku se moramo ukvarjati tudi s primeri napak. Za zdaj bomo dodali le sporočilo v dnevnik, da prikažemo napako, in se k temu vrnili kasneje. Nato moramo podatke shraniti nekam, da jih lahko kasneje uporabimo za prikaz informacij na nadzorni plošči. Ker spremenljivka `account` še ne obstaja, bomo na vrhu naše datoteke ustvarili globalno spremenljivko: ```js let account = null; ``` Ko so uporabniški podatki shranjeni v spremenljivko, lahko preidemo s strani *login* na *dashboard* z uporabo funkcije `navigate()`, ki jo že imamo. Nazadnje moramo poklicati našo funkcijo `login`, ko je obrazec za prijavo oddan, tako da spremenimo HTML: ```html