# Izgradnja bankovne aplikacije, dio 3: Metode dohvaćanja i korištenja podataka ## Kviz prije predavanja [Kviz prije predavanja](https://ff-quizzes.netlify.app/web/quiz/45) ### Uvod U središtu svake web aplikacije nalaze se *podaci*. Podaci mogu imati različite oblike, ali njihova glavna svrha uvijek je prikazivanje informacija korisniku. Kako web aplikacije postaju sve interaktivnije i složenije, način na koji korisnik pristupa i komunicira s informacijama postaje ključni dio razvoja weba. U ovoj lekciji vidjet ćemo kako asinkrono dohvatiti podatke sa servera i koristiti te podatke za prikaz informacija na web stranici bez ponovnog učitavanja HTML-a. ### Preduvjeti Potrebno je da ste izradili [Formu za prijavu i registraciju](../2-forms/README.md) kao dio web aplikacije za ovu lekciju. Također trebate instalirati [Node.js](https://nodejs.org) i [pokrenuti API server](../api/README.md) lokalno kako biste dobili podatke o korisničkim računima. Možete testirati radi li server ispravno izvršavanjem ove naredbe u terminalu: ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## AJAX i dohvaćanje podataka Tradicionalne web stranice ažuriraju prikazani sadržaj kada korisnik odabere poveznicu ili pošalje podatke putem forme, ponovno učitavajući cijelu HTML stranicu. Svaki put kada je potrebno učitati nove podatke, web server vraća potpuno novu HTML stranicu koju preglednik mora obraditi, prekidajući trenutnu korisničku akciju i ograničavajući interakcije tijekom učitavanja. Ovaj način rada naziva se *Višestranična aplikacija* ili *MPA*.  Kako su web aplikacije postajale složenije i interaktivnije, pojavila se nova tehnika nazvana [AJAX (Asynchronous JavaScript and XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Ova tehnika omogućuje web aplikacijama slanje i dohvaćanje podataka sa servera asinkrono pomoću JavaScripta, bez potrebe za ponovnim učitavanjem HTML stranice, što rezultira bržim ažuriranjima i glatkijim korisničkim interakcijama. Kada se novi podaci dobiju sa servera, trenutna HTML stranica može se ažurirati pomoću JavaScripta koristeći [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. S vremenom se ovaj pristup razvio u ono što se danas naziva [*Jednostranična aplikacija* ili *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  Kada je AJAX prvi put uveden, jedini dostupni API za asinkrono dohvaćanje podataka bio je [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). No, moderni preglednici sada implementiraju praktičniji i moćniji [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), koji koristi obećanja (promises) i bolje je prilagođen za manipulaciju JSON podacima. > Iako svi moderni preglednici podržavaju `Fetch API`, ako želite da vaša web aplikacija radi na starijim preglednicima, uvijek je dobra ideja provjeriti [tablicu kompatibilnosti na caniuse.com](https://caniuse.com/fetch). ### Zadatak U [prethodnoj lekciji](../2-forms/README.md) implementirali smo formu za registraciju kako bismo kreirali korisnički račun. Sada ćemo dodati kod za prijavu koristeći postojeći račun i dohvat njegovih podataka. Otvorite datoteku `app.js` i dodajte novu funkciju `login`: ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; } ``` Ovdje započinjemo dohvaćanjem elementa forme pomoću `getElementById()`, a zatim dobivamo korisničko ime iz unosa pomoću `loginForm.user.value`. Svaki kontrolni element forme može se pristupiti putem njegovog imena (postavljenog u HTML-u pomoću atributa `name`) kao svojstva forme. Na sličan način kao što smo učinili za registraciju, kreirat ćemo drugu funkciju za izvršavanje zahtjeva prema serveru, ali ovaj put za dohvaćanje podataka 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' }; } } ``` Koristimo `fetch` API za asinkrono dohvaćanje podataka sa servera, ali ovaj put ne trebamo dodatne parametre osim URL-a koji pozivamo, jer samo tražimo podatke. Po defaultu, `fetch` kreira [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP zahtjev, što je upravo ono što nam treba. ✅ `encodeURIComponent()` je funkcija koja kodira posebne znakove za URL. Koje probleme bismo mogli imati ako ne pozovemo ovu funkciju i direktno koristimo vrijednost `user` u URL-u? Sada ćemo ažurirati našu funkciju `login` kako bismo koristili `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'); } ``` Prvo, budući da je `getAccount` asinkrona funkcija, moramo je uskladiti s ključnom riječi `await` kako bismo pričekali rezultat servera. Kao i kod svakog zahtjeva prema serveru, također moramo obraditi slučajeve pogreške. Za sada ćemo samo dodati poruku u log za prikaz pogreške i vratiti se na to kasnije. Zatim moramo pohraniti podatke negdje kako bismo ih kasnije mogli koristiti za prikaz informacija na nadzornoj ploči. Budući da varijabla `account` još ne postoji, kreirat ćemo globalnu varijablu na vrhu naše datoteke: ```js let account = null; ``` Nakon što su korisnički podaci spremljeni u varijablu, možemo se prebaciti s *login* stranice na *dashboard* koristeći funkciju `navigate()` koju već imamo. Na kraju, trebamo pozvati našu funkciju `login` kada se forma za prijavu pošalje, modificirajući HTML: ```html