# Izrada bankarske aplikacije - dio 3: Načini dohvaćanja i korištenja podataka Razmislite o Enterpriseovom računalu u Star Treku - kada kapetan Picard zatraži status broda, informacije se pojavljuju odmah bez da se cijeli sučelje zaustavi i ponovno sastavi. Taj besprijekoran tijek informacija upravo gradimo ovdje s dinamičkim dohvaćanjem podataka. Trenutno je vaša banka unutar aplikacije poput tiskanih novina - informativna, ali statična. Pretvorit ćemo je u nešto poput kontrolnog centra NASA-e, gdje podaci kontinuirano teku i ažuriraju se u stvarnom vremenu bez prekidanja korisničkog tijeka rada. Naučit ćete kako asinkrono komunicirati sa serverima, rukovati podacima koji dolaze u različito vrijeme i pretvarati sirove informacije u nešto smisleno za vaše korisnike. Ovo je razlika između demonstracije i softvera spremnog za produkciju. ## ⚡ Što možete napraviti u sljedećih 5 minuta **Brzi put za zaposlene programere** ```mermaid flowchart LR A[⚡ 5 minuta] --> B[Postavi API poslužitelj] B --> C[Isprobaj dohvaćanje s curlom] C --> D[Izradi funkciju za prijavu] D --> E[Pogledaj podatke u akciji] ``` - **Minuta 1-2**: Pokrenite svoj API server (`cd api && npm start`) i testirajte vezu - **Minuta 3**: Napravite osnovnu funkciju `getAccount()` koristeći fetch - **Minuta 4**: Povežite login formu s `action="javascript:login()"` - **Minuta 5**: Testirajte login i pratite pojavu podataka o računu u konzoli **Brze testne naredbe**: ```bash # Provjerite radi li API curl http://localhost:5000/api # Testirajte dohvaćanje podataka računa curl http://localhost:5000/api/accounts/test ``` **Zašto je ovo važno**: U 5 minuta vidjet ćete magiju asinkronog dohvaćanja podataka koja pokreće svaku modernu web aplikaciju. Ovo je temelj koji aplikacijama daje osjećaj odzivnosti i živosti. ## 🗺️ Vaše putovanje kroz podatkovno vođene web aplikacije ```mermaid journey title Od statičkih stranica do dinamičkih aplikacija section Razumijevanje evolucije Tradicionalna ponovna učitavanja stranica: 3: You Otkrijte prednosti AJAX/SPA: 5: You Savladajte obrasce Fetch API-ja: 7: You section Izgradnja autentifikacije Izradite funkcije prijave: 4: You Rukujte asinkronim operacijama: 6: You Upravljajte korisničkim sesijama: 8: You section Dinamičke ažuriranja UI-a Naučite manipulaciju DOM-om: 5: You Izradite prikaze transakcija: 7: You Izradite responzivne nadzorne ploče: 9: You section Profesionalni obrasci Renderiranje temeljeno na predlošcima: 6: You Strategije rukovanja greškama: 7: You Optimizacija performansi: 8: You ``` **Cilj vašeg putovanja**: Do kraja ove lekcije razumjet ćete kako moderne web aplikacije dohvaćaju, obrađuju i prikazuju podatke dinamički, stvarajući besprijekorna korisnička iskustva koja očekujemo od profesionalnih aplikacija. ## Predpredavanje Kviza [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/45) ### Preduvjeti Prije nego što zaronite u dohvaćanje podataka, osigurajte da imate spremne ove komponente: - **Prethodna lekcija**: Završite [Login i registracijski obrazac](../2-forms/README.md) - na tome ćemo graditi - **Lokalni server**: Instalirajte [Node.js](https://nodejs.org) i [pokrenite API server](../api/README.md) za pružanje podataka o računu - **API veza**: Testirajte vezu sa serverom ovom naredbom: ```bash curl http://localhost:5000/api # Očekivani odgovor: "Bank API v1.0.0" ``` Ovaj brzi test osigurava da svi dijelovi ispravno komuniciraju: - Provjerava radi li Node.js ispravno na vašem sustavu - Potvrđuje da je vaš API server aktivan i odgovara - Validira da vaša aplikacija može doći do servera (kao provjera radio veze prije misije) ## 🧠 Pregled ekosustava za upravljanje podacima ```mermaid mindmap root((Upravljanje podacima)) Authentication Flow Login Process Form Validation Credential Verification Session Management User State Global Account Object Navigation Guards Error Handling API Communication Fetch Patterns GET Requests POST Requests Error Responses Data Formats JSON Processing URL Encoding Response Parsing Dynamic UI Updates DOM Manipulation Safe Text Updates Element Creation Template Cloning User Experience Real-time Updates Error Messages Loading States Security Considerations XSS Prevention textContent Usage Input Sanitization Safe HTML Creation CORS Handling Cross-Origin Requests Header Configuration Development Setup ``` **Osnovni princip**: Moderne web aplikacije su sustavi za orkestraciju podataka - koordiniraju između korisničkih sučelja, API servera i sigurnosnih modela preglednika kako bi stvorile besprijekorna, responzivna iskustva. --- ## Razumijevanje dohvaćanja podataka u modernim web aplikacijama Način na koji web aplikacije rukuju podacima dramatično se razvio tijekom posljednja dva desetljeća. Razumijevanje te evolucije pomoći će vam shvatiti zašto su moderne tehnike poput AJAX-a i Fetch API-ja toliko moćne i zašto su postale ključni alati web programera. Istražimo kako su tradicionalne web-stranice funkcionirale u odnosu na dinamične, responzivne aplikacije koje danas gradimo. ### Tradicionalne više-stranične aplikacije (MPA) U ranim danima weba, svaki klik bio je poput promjene kanala na starom televizoru - zaslon bi potamnio, zatim se polako napunio novim sadržajem. Tako je bilo u ranim web aplikacijama, gdje je svaka interakcija značila potpuno ponovno građenje cijele stranice ispočetka. ```mermaid sequenceDiagram participant User participant Browser participant Server User->>Browser: Klikne na vezu ili pošalje obrazac Browser->>Server: Zahtijeva novu HTML stranicu Note over Browser: Stranica postaje prazna Server->>Browser: Vraća kompletnu HTML stranicu Browser->>User: Prikazuje novu stranicu (kašalj/ponovno učitavanje) ``` ![Radni tijek ažuriranja u više-straničnoj aplikaciji](../../../../translated_images/hr/mpa.7f7375a1a2d4aa77.webp) **Zašto je taj pristup djelovao nezgrapno:** - Svaki klik značio je potpuno ponovno građenje stranice od nule - Korisnici su bili prekidani usred misli onim dosadnim bljeskovima stranice - Vaša internetska veza je prekomjerno preuzimala isti zaglavlje i podnožje više puta - Aplikacije su više djelovale kao klikanje kroz arhivski ormar nego korištenje softvera ### Moderne jedno-stranične aplikacije (SPA) AJAX (Asinhroni JavaScript i XML) potpuno je promijenio ovaj paradigmu. Kao modularni dizajn Međunarodne svemirske postaje, gdje astronauti mogu zamijeniti pojedine dijelove bez hitnog rekonstrukcije sustava, AJAX omogućuje da ažuriramo specifične dijelove web stranice bez ponovnog učitavanja svega. Iako naziv spominje XML, danas najviše koristimo JSON, ali osnovni princip ostaje isti: mijenjamo samo ono što treba. ```mermaid sequenceDiagram participant User participant Browser participant JavaScript participant Server User->>Browser: Interagira sa stranicom Browser->>JavaScript: Okida rukovatelj događaja JavaScript->>Server: Dohvaća samo potrebne podatke Server->>JavaScript: Vraća JSON podatke JavaScript->>Browser: Ažurira određene elemente stranice Browser->>User: Prikazuje ažurirani sadržaj (bez ponovnog učitavanja) ``` ![Radni tijek ažuriranja u jedno-straničnoj aplikaciji](../../../../translated_images/hr/spa.268ec73b41f992c2.webp) **Zašto SPA aplikacije djeluju puno bolje:** - Ažuriraju samo dijelove koji su stvarno promijenjeni (pametno, zar ne?) - Nema više bolnih prekida - korisnici ostaju u svom tijeku rada - Manje podataka putuje mrežom, što znači brže učitavanje - Sve djeluje brzo i responzivno, kao aplikacije na vašem telefonu ### Evolucija do modernog Fetch API-ja Moderni preglednici pružaju [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), koji zamjenjuje stariji [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Kao razlika između rada s telegrafom i korištenja elektroničke pošte, Fetch API koristi promiseove za čišći asinhroni kod i prirodno rukuje JSON-om. | Značajka | XMLHttpRequest | Fetch API | |---------|----------------|----------| | **Sintaksa** | Složene povratne funkcije | Čist kod baziran na promisevima | | **Rukovanje JSON-om** | Ručna obrada potrebna | Ugrađena `.json()` metoda | | **Rukovanje greškama** | Ograničene informacije | Sveobuhvatni detalji o pogreškama | | **Moderna podrška** | Kompatibilnost sa starijim verzijama | ES6+ promise i async/await | > 💡 **Kompatibilnost preglednika**: Dobre vijesti - Fetch API radi u svim modernim preglednicima! Ako vas zanimaju specifične verzije, [caniuse.com](https://caniuse.com/fetch) ima kompletnu priču o kompatibilnosti. > **Zaključak:** - Odlično radi u Chromeu, Firefoxu, Safariu i Edgeu (prakticno svugdje gdje su vaši korisnici) - Samo Internet Explorer treba dodatnu pomoć (i iskreno, vrijeme je da ga pustimo) - Savršeno vas priprema za elegantne async/await obrasce koje ćemo koristiti kasnije ### Implementacija korisničkog prijavljivanja i dohvaćanja podataka Sad ćemo implementirati sustav za prijavu koji vašu bankarsku aplikaciju pretvara iz statičnog prikaza u funkcionalnu aplikaciju. Kao autentični protokoli u sigurnim vojnim objektima, provjerit ćemo korisničke vjerodajnice i zatim pružiti pristup njihovim specifičnim podacima. Gradit ćemo to inkrementalno, počevši s osnovnim ovjeravanjem, a zatim dodajući mogućnosti dohvaćanja podataka. #### Korak 1: Izradite osnovu funkcije login Otvorite svoj `app.js` fajl i dodajte novu funkciju `login`. Ova će upravljati procesom autentifikacije korisnika: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **Objasnimo ovo:** - Ta `async` riječ? Govori JavaScriptu "hej, ova funkcija možda će morati pričekati nešto" - Hvatamo naš obrazac s stranice (nema ništa posebno, samo ga pronalazimo po njegovom ID-u) - Izvlačimo što god je korisnik upisao kao korisničko ime - Evo zgodnog trika: možete pristupiti bilo kojem elementu forme po njegovom `name` atributu - nema potrebe za dodatnim pozivima getElementById! > 💡 **Obrazac pristupa**: Svakom kontrolnom elementu obrasca može se pristupiti po imenu (postavljeno u HTML-u koristeći atribut `name`) kao svojstvu forme. Ovo pruža čist i čitljiv način dohvaćanja podataka iz forme. #### Korak 2: Izradite funkciju za dohvaćanje podataka o računu Zatim ćemo napraviti posebnu funkciju za dohvaćanje podataka o računu sa servera. Ovo slijedi isti obrazac kao i vaša funkcija registracije, ali fokusira se na dohvaćanje podataka: ```javascript 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' }; } } ``` **Evo što ovaj kod radi:** - **Koristi** moderni `fetch` API za asinhroni zahtjev podataka - **Gradi** URL za GET zahtjev s parametrima korisničkog imena - **Primjenjuje** `encodeURIComponent()` za sigurno rukovanje posebnim znakovima u URL-ovima - **Pretvara** odgovor u JSON za jednostavnu obradu podataka - **Rukuje** greškama na elegantan način vraćajući objekt s greškom umjesto pada > ⚠️ **Sigurnosna napomena**: Funkcija `encodeURIComponent()` rukuje posebnim znakovima u URL-ovima. Kao kodovi u pomorskoj komunikaciji, osigurava da vaša poruka stigne točno onako kako treba, sprečavajući da znakovi poput "#" ili "&" budu pogrešno protumačeni. > **Zašto je ovo važno:** - Sprečava da posebni znakovi slome URL - Štiti od napada manipulacije URL-om - Osigurava da server dobije točne podatke - Prati sigurne prakse kodiranja #### Razumijevanje HTTP GET zahtjeva Evo nečega što bi vas moglo iznenaditi: kada koristite `fetch` bez dodatnih opcija, on automatski stvara [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) zahtjev. To je savršeno za ono što radimo - pitamo server "hej, mogu li vidjeti podatke ovog korisničkog računa?" Razmislite o GET zahtjevima kao ljubaznom traženju posudbe knjige u knjižnici - tražite nešto što već postoji. POST zahtjevi (koje smo koristili za registraciju) su poput slanja nove knjige da se doda u zbirku. | GET Zahtjev | POST Zahtjev | |-------------|--------------| | **Svrha** | Dohvaćanje postojećih podataka | Slanje novih podataka serveru | | **Parametri** | U URL putanji/upitu | U tijelu zahtjeva | | **Keširanje** | Može biti keširano od strane preglednika | Obično se ne kešira | | **Sigurnost** | Vidljivo u URL-u/zapisima | Sakriveno u tijelu zahtjeva | ```mermaid sequenceDiagram participant B as Preglednik participant S as Poslužitelj Note over B,S: GET Zahtjev (Preuzimanje Podataka) B->>S: GET /api/accounts/test S-->>B: 200 OK + Podaci Računa Note over B,S: POST Zahtjev (Slanje Podataka) B->>S: POST /api/accounts + Novi Podaci Računa S-->>B: 201 Stvoreno + Potvrda Note over B,S: Obrada Pogrešaka B->>S: GET /api/accounts/nepostojeći S-->>B: 404 Nije Pronađeno + Poruka o Pogrešci ``` #### Korak 3: Sve povezujemo zajedno Sad onaj zadovoljavajući dio - povežimo vašu funkciju dohvaćanja računa s procesom prijave. Ovo je trenutak gdje sve dolazi na svoje mjesto: ```javascript 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'); } ``` Ova funkcija slijedi jasan slijed: - Izvlači korisničko ime iz obrasca - Traži podatke korisničkog računa sa servera - Rukuje bilo kakvim greškama tijekom procesa - Spremi podatke računa i preusmjeri na nadzornu ploču ako je uspješno > 🎯 **Async/Await obrazac**: Budući da je `getAccount` asinhrona funkcija, koristimo ključnu riječ `await` da pauziramo izvršenje dok server ne odgovori. Time sprječavamo da kod nastavi raditi s nepoznatim podacima. #### Korak 4: Stvaranje mjesta za vaše podatke Vašoj aplikaciji treba mjesto za pamćenje podataka o računu nakon što su učitani. Pomislite na to kao kratkoročnu memoriju vaše aplikacije - mjesto za pohranu podataka trenutnog korisnika pod rukom. Dodajte ovaj redak na vrh datoteke `app.js`: ```javascript // Ovo sadrži podatke trenutnog korisničkog računa let account = null; ``` **Zašto nam treba ovo:** - Čuva dostupne podatke o računu s bilo kojeg mjesta u aplikaciji - Početna vrijednost `null` znači "nitko još nije prijavljen" - Ažurira se kad se netko uspješno prijavi ili registrira - Djeluje kao jedini izvor istine - nema zbunjenosti tko je prijavljen #### Korak 5: Povežite vaš obrazac Sada povežimo vašu novu login funkciju s HTML formom. Ažurirajte svoj tag forme ovako: ```html
``` **Što ova mala promjena radi:** - Sprječava da forma radi svoju zadanu akciju "ponovno učitavanje cijele stranice" - Poziva vašu prilagođenu JavaScript funkciju umjesto toga - Održava sve glatkim i slično SPA aplikacijama - Daje vam potpunu kontrolu nad onim što se događa kad korisnici kliknu "Login" #### Korak 6: Poboljšajte funkciju registracije Radi dosljednosti, ažurirajte vašu funkciju `register` da također sprema podatke o računu i preusmjerava na nadzornu ploču: ```javascript // Dodajte ove retke na kraj vaše funkcije register account = result; navigate('/dashboard'); ``` **Ovo poboljšanje pruža:** - **Neprekidan** prijelaz od registracije do nadzorne ploče - **Dosljedan** korisnički dojam između prijave i registracije - **Trenutni** pristup podacima računa nakon uspješne registracije #### Testiranje vaše implementacije ```mermaid flowchart TD A[Korisnik unosi vjerodajnice] --> B[Pozvana funkcija prijave] B --> C[Dohvati podatke računa sa servera] C --> D{Podaci su uspješno primljeni?} D -->|Da| E[Spremi podatke računa globalno] D -->|Ne| F[Prikaži poruku o pogrešci] E --> G[Navigiraj na nadzornu ploču] F --> H[Korisnik ostaje na stranici prijave] ``` **Vrijeme je za testiranje:** 1. Kreirajte novi račun da se uvjerite da sve radi 2. Pokušajte se prijaviti s istim vjerodajnicama 3. Pogledajte konzolu preglednika (F12) ako nešto izgleda čudno 4. Provjerite da li ste preusmjereni na nadzornu ploču nakon uspješne prijave Ako nešto ne radi, ne paničarite! Većina problema su male greške poput tipfelera ili zaborava pokretanja API servera. #### Kratka riječ o magiji Cross-Origin Možda se pitate: "Kako moja web aplikacija komunicira s ovim API serverom ako rade na različitim portovima?" Odlično pitanje! Ovo je nešto što svaki web developer prije ili kasnije susretne. > 🔒 **Cross-Origin sigurnost**: Preglednici primjenjuju "pravilo iste domene" da spriječe neovlaštenu komunikaciju između različitih domena. Kao kontrolni punkt u Pentagonskoj zgradi, oni provjeravaju je li komunikacija odobrena prije omogućavanja prijenosa podataka. > **U našem slučaju:** - Vaša web aplikacija radi na `localhost:3000` (razvojni server) - Vaš API server radi na `localhost:5000` (backend server) - API server uključuje [CORS zaglavlja](https://developer.mozilla.org/docs/Web/HTTP/CORS) koja izričito dopuštaju komunikaciju s vaše web aplikacije Ovo je česta konfiguracija u razvoju gdje frontend i backend obično rade na različitim serverima. > 📚 **Saznajte više**: Dublje istražite API-je i dohvaćanje podataka u ovom opsežnom [Microsoft Learn modulu o API-jima](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Oživljavanje vaših podataka u HTML-u Sad ćemo učiniti dohvaćene podatke vidljivima korisnicima kroz manipulaciju DOM-om. Kao proces razvijanja fotografija u mračnoj komori, uzimamo nevidljive podatke i prikazujemo ih u nečemu što korisnici mogu vidjeti i s čim mogu komunicirati. Manipulacija DOM-om je tehnika koja pretvara statične web stranice u dinamičke aplikacije koje ažuriraju svoj sadržaj na temelju korisničkih interakcija i odgovora poslužitelja. ### Odabir Pravog Alata za Posao Kad je riječ o ažuriranju vašeg HTML-a s JavaScriptom, imate nekoliko opcija. Zamislite ih kao različite alate u kutiji s alatima - svaki savršen za određene zadatke: | Metoda | Za što je izvrsna | Kada je koristiti | Razina sigurnosti | |--------|-------------------|------------------|-------------------| | `textContent` | Sigurno prikazivanje korisničkih podataka | Kad god prikazujete tekst | ✅ Čvrsto kao stijena | | `createElement()` + `append()` | Izrada složenih rasporeda | Kreiranje novih sekcija/lista | ✅ Neprobojno | | `innerHTML` | Postavljanje HTML sadržaja | ⚠️ Pokušajte ovo izbjegavati | ❌ Rizično poslovanje | #### Siguran Način za Prikaz Teksta: textContent Svojstvo [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) je vaš najbolji prijatelj kad prikazujete korisničke podatke. Kao da imate portira na svojoj web stranici - ništa štetno ne prolazi: ```javascript // Siguran, pouzdan način za ažuriranje teksta const balanceElement = document.getElementById('balance'); balanceElement.textContent = account.balance; ``` **Prednosti textContent:** - Sve tretira kao običan tekst (sprječava izvršavanje skripti) - Automatski briše postojeći sadržaj - Učinkovit za jednostavna ažuriranja teksta - Pruža ugrađenu sigurnost protiv zlonamjernog sadržaja #### Izrada Dinamičkih HTML Elemenata Za složeniji sadržaj, kombinirajte [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) s metodom [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append): ```javascript // Siguran način za stvaranje novih elemenata const transactionItem = document.createElement('div'); transactionItem.className = 'transaction-item'; transactionItem.textContent = `${transaction.date}: ${transaction.description}`; container.append(transactionItem); ``` **Razumijevanje ovog pristupa:** - **Stvara** nove DOM elemente programatski - **Održava** punu kontrolu nad atributima i sadržajem elemenata - **Omogućuje** složene, ugniježdene strukture elemenata - **Čuva** sigurnost odvajanjem strukture od sadržaja > ⚠️ **Sigurnosna Napomena**: Iako se [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) često pojavljuje u tutorijalima, može izvršavati ugrađene skripte. Kao što sigurnosni protokoli u CERN-u sprječavaju neovlašteno izvršavanje koda, korištenje `textContent` i `createElement` nudi sigurnije alternative. > **Rizici innerHTML:** - Izvršava sve `