# Vytvoření bankovní aplikace, část 3: Metody získávání a používání dat Představte si počítač Enterprise ze Star Treku – když kapitán Picard požádá o stav lodi, informace se okamžitě zobrazí, aniž by se celé rozhraní muselo vypnout a znovu načíst. Přesně takový plynulý tok informací se snažíme vytvořit pomocí dynamického získávání dat. Vaše bankovní aplikace je momentálně jako tištěné noviny – informativní, ale statická. Proměníme ji v něco podobného řídícímu centru NASA, kde data proudí nepřetržitě a aktualizují se v reálném čase, aniž by narušovala uživatelský zážitek. Naučíte se komunikovat se servery asynchronně, pracovat s daty, která přicházejí v různých časech, a transformovat surové informace na něco smysluplného pro vaše uživatele. To je rozdíl mezi ukázkovým a produkčně připraveným softwarem. ## Kvíz před přednáškou [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/45) ### Předpoklady Než se pustíte do získávání dat, ujistěte se, že máte připraveny tyto komponenty: - **Předchozí lekce**: Dokončete [Přihlašovací a registrační formulář](../2-forms/README.md) – budeme na tomto základě stavět - **Lokální server**: Nainstalujte [Node.js](https://nodejs.org) a [spusťte server API](../api/README.md), který poskytne data o účtu - **Připojení k API**: Otestujte připojení k serveru tímto příkazem: ```bash curl http://localhost:5000/api # Expected response: "Bank API v1.0.0" ``` Tento rychlý test zajistí, že všechny komponenty správně komunikují: - Ověří, že Node.js na vašem systému běží správně - Potvrdí, že váš API server je aktivní a reaguje - Ověří, že vaše aplikace může dosáhnout na server (jako kontrola rádiového spojení před misí) --- ## Porozumění získávání dat v moderních webových aplikacích Způsob, jakým webové aplikace pracují s daty, se za poslední dvě desetiletí dramaticky vyvinul. Pochopení tohoto vývoje vám pomůže ocenit, proč jsou moderní techniky jako AJAX a Fetch API tak silné a proč se staly nezbytnými nástroji pro webové vývojáře. Pojďme prozkoumat, jak fungovaly tradiční webové stránky ve srovnání s dynamickými, responzivními aplikacemi, které dnes vytváříme. ### Tradiční více stránkové aplikace (MPA) V počátcích webu byl každý klik jako přepínání kanálů na staré televizi – obrazovka zčernala a poté se pomalu naladil nový obsah. Taková byla realita raných webových aplikací, kde každá interakce znamenala kompletní přestavbu celé stránky od začátku. ```mermaid sequenceDiagram participant User participant Browser participant Server User->>Browser: Clicks link or submits form Browser->>Server: Requests new HTML page Note over Browser: Page goes blank Server->>Browser: Returns complete HTML page Browser->>User: Displays new page (flash/reload) ```  **Proč tento přístup působil neohrabaně:** - Každý klik znamenal kompletní přestavbu celé stránky od začátku - Uživatelé byli přerušováni nepříjemnými záblesky stránky - Vaše internetové připojení pracovalo přesčas při stahování stejných záhlaví a zápatí opakovaně - Aplikace působily spíše jako procházení kartotéky než jako používání softwaru ### Moderní jednostránkové aplikace (SPA) AJAX (Asynchronous JavaScript and XML) zcela změnil tento přístup. Stejně jako modulární design Mezinárodní vesmírné stanice, kde astronauti mohou vyměnit jednotlivé komponenty bez přestavby celé struktury, AJAX nám umožňuje aktualizovat konkrétní části webové stránky bez jejího kompletního znovunačtení. I když název zmiňuje XML, dnes většinou používáme JSON, ale základní princip zůstává: aktualizovat pouze to, co se musí změnit. ```mermaid sequenceDiagram participant User participant Browser participant JavaScript participant Server User->>Browser: Interacts with page Browser->>JavaScript: Triggers event handler JavaScript->>Server: Fetches only needed data Server->>JavaScript: Returns JSON data JavaScript->>Browser: Updates specific page elements Browser->>User: Shows updated content (no reload) ```  **Proč jsou SPA tak příjemné:** - Aktualizují se pouze části, které se skutečně změnily (chytré, že?) - Žádné rušivé přerušení – uživatelé zůstávají ve svém pracovním toku - Méně dat putuje po síti, což znamená rychlejší načítání - Všechno působí svižně a responzivně, jako aplikace na vašem telefonu ### Vývoj k modernímu Fetch API Moderní prohlížeče poskytují [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), které nahrazuje starší [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Stejně jako rozdíl mezi ovládáním telegrafu a používáním e-mailu, Fetch API používá promises pro čistší asynchronní kód a přirozeně pracuje s JSON. | Funkce | XMLHttpRequest | Fetch API | |--------|----------------|-----------| | **Syntaxe** | Složitá, založená na zpětných voláních | Čistá, založená na promises | | **Práce s JSON** | Nutné ruční parsování | Vestavěná metoda `.json()` | | **Zpracování chyb** | Omezené informace o chybách | Komplexní detaily o chybách | | **Podpora moderních prohlížečů** | Kompatibilita se staršími verzemi | ES6+ promises a async/await | > 💡 **Kompatibilita prohlížečů**: Dobrá zpráva – Fetch API funguje ve všech moderních prohlížečích! Pokud vás zajímají konkrétní verze, [caniuse.com](https://caniuse.com/fetch) má kompletní příběh o kompatibilitě. > **Shrnutí:** - Funguje skvěle v Chrome, Firefoxu, Safari a Edge (prakticky všude, kde jsou vaši uživatelé) - Pouze Internet Explorer potřebuje dodatečnou pomoc (a upřímně, je čas se s IE rozloučit) - Perfektně se hodí pro elegantní vzory async/await, které budeme používat později ### Implementace přihlášení uživatele a získávání dat Nyní implementujeme přihlašovací systém, který promění vaši bankovní aplikaci ze statického zobrazení na funkční aplikaci. Stejně jako autentizační protokoly používané v zabezpečených vojenských zařízeních ověříme přihlašovací údaje uživatele a poté mu poskytneme přístup k jeho konkrétním datům. Budeme postupovat krok za krokem, začneme základní autentizací a poté přidáme schopnosti získávání dat. #### Krok 1: Vytvoření základní funkce pro přihlášení Otevřete soubor `app.js` a přidejte novou funkci `login`. Ta bude zajišťovat proces autentizace uživatele: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **Rozbor kódu:** - Klíčové slovo `async` říká JavaScriptu „hej, tato funkce možná bude muset na něco počkat“ - Najdeme formulář na stránce (nic složitého, prostě ho najdeme podle jeho ID) - Poté získáme, co uživatel zadal jako své uživatelské jméno - Malý trik: k jakémukoli vstupu formuláře můžete přistupovat pomocí atributu `name` – není potřeba dalších volání getElementById! > 💡 **Vzor přístupu k formuláři**: Ke každému ovládacímu prvku formuláře lze přistupovat podle jeho názvu (nastaveného v HTML pomocí atributu `name`) jako k vlastnosti elementu formuláře. To poskytuje čistý a čitelný způsob získávání dat z formuláře. #### Krok 2: Vytvoření funkce pro získávání dat o účtu Dále vytvoříme dedikovanou funkci pro získávání dat o účtu ze serveru. Ta bude následovat stejný vzor jako vaše registrační funkce, ale zaměří se na získávání dat: ```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' }; } } ``` **Co tento kód zajišťuje:** - **Používá** moderní `fetch` API pro asynchronní požadavky na data - **Sestavuje** URL GET požadavku s parametrem uživatelského jména - **Aplikuje** `encodeURIComponent()` pro bezpečné zpracování speciálních znaků v URL - **Převádí** odpověď na formát JSON pro snadnou manipulaci s daty - **Zpracovává** chyby elegantně tím, že vrací objekt chyby místo pádu aplikace > ⚠️ **Bezpečnostní poznámka**: Funkce `encodeURIComponent()` zpracovává speciální znaky v URL. Stejně jako kódovací systémy používané v námořní komunikaci zajišťuje, že vaše zpráva dorazí přesně tak, jak byla zamýšlena, a zabrání tomu, aby byly znaky jako "#" nebo "&" špatně interpretovány. > **Proč na tom záleží:** - Zabraňuje speciálním znakům v narušení URL - Chrání před útoky manipulací s URL - Zajišťuje, že server obdrží zamýšlená data - Dodržuje bezpečné postupy při programování #### Porozumění HTTP GET požadavkům Možná vás překvapí: když použijete `fetch` bez dalších možností, automaticky vytvoří [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) požadavek. To je ideální pro to, co děláme – ptáme se serveru „hej, můžu vidět data tohoto uživatele?“ Představte si GET požadavky jako zdvořilé žádosti o půjčení knihy z knihovny – žádáte o něco, co už existuje. POST požadavky (které jsme použili pro registraci) jsou spíše jako odevzdání nové knihy, která má být přidána do sbírky. | GET požadavek | POST požadavek | |---------------|----------------| | **Účel** | Získání existujících dat | Odeslání nových dat na server | | **Parametry** | V cestě URL/řetězci dotazu | V těle požadavku | | **Caching** | Může být cachováno prohlížeči | Obvykle není cachováno | | **Bezpečnost** | Viditelné v URL/logech | Skryté v těle požadavku | #### Krok 3: Spojení všeho dohromady Nyní přichází uspokojivá část – spojíme vaši funkci pro získávání dat o účtu s procesem přihlášení. Tady vše zapadne na své místo: ```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'); } ``` Tato funkce následuje jasnou sekvenci: - Získá uživatelské jméno z vstupu formuláře - Požádá server o data uživatelského účtu - Zpracuje jakékoli chyby, které se během procesu vyskytnou - Uloží data o účtu a po úspěšném přihlášení přejde na dashboard > 🎯 **Vzor async/await**: Protože `getAccount` je asynchronní funkce, používáme klíčové slovo `await`, abychom pozastavili provádění, dokud server neodpoví. To zabrání pokračování kódu s nedefinovanými daty. #### Krok 4: Vytvoření místa pro vaše data Vaše aplikace potřebuje místo, kde si zapamatuje informace o účtu, jakmile budou načteny. Představte si to jako krátkodobou paměť vaší aplikace – místo, kde si uchová aktuální data uživatele. Přidejte tento řádek na začátek vašeho souboru `app.js`: ```javascript // This holds the current user's account data let account = null; ``` **Proč to potřebujeme:** - Udržuje data o účtu dostupná odkudkoli v aplikaci - Začíná s hodnotou `null`, což znamená „zatím nikdo není přihlášen“ - Aktualizuje se, když se někdo úspěšně přihlásí nebo zaregistruje - Funguje jako jediný zdroj pravdy – žádné zmatky o tom, kdo je přihlášen #### Krok 5: Propojení vašeho formuláře Nyní připojíme vaši novou funkci přihlášení k HTML formuláři. Aktualizujte tag formuláře takto: ```html
``` **Co tato malá změna dělá:** - Zastaví formulář, aby nedělal své výchozí „znovunačtení celé stránky“ - Místo toho zavolá vaši vlastní JavaScriptovou funkci - Udržuje vše hladké a ve stylu jednostránkové aplikace - Dává vám úplnou kontrolu nad tím, co se stane, když uživatelé kliknou na „Přihlásit se“ #### Krok 6: Vylepšení registrační funkce Pro konzistenci aktualizujte svou funkci `register`, aby také ukládala data o účtu a přecházela na dashboard: ```javascript // Add these lines at the end of your register function account = result; navigate('/dashboard'); ``` **Toto vylepšení poskytuje:** - **Plynulý** přechod z registrace na dashboard - **Konzistentní** uživatelský zážitek mezi přihlašovacími a registračními procesy - **Okamžitý** přístup k datům o účtu po úspěšné registraci #### Testování vaší implementace ```mermaid flowchart TD A[User enters credentials] --> B[Login function called] B --> C[Fetch account data from server] C --> D{Data received successfully?} D -->|Yes| E[Store account data globally] D -->|No| F[Display error message] E --> G[Navigate to dashboard] F --> H[User stays on login page] ``` **Čas to vyzkoušet:** 1. Vytvořte nový účet, abyste se ujistili, že vše funguje 2. Zkuste se přihlásit pomocí stejných přihlašovacích údajů 3. Podívejte se do konzole prohlížeče (F12), pokud se něco zdá být špatně 4. Ujistěte se, že po úspěšném přihlášení přistáváte na dashboardu Pokud něco nefunguje, nepanikařte! Většina problémů jsou jednoduché opravy, jako překlepy nebo zapomenutí spustit API server. #### Rychlé slovo o magii mezi doménami Možná vás zajímá: „Jak moje webová aplikace komunikuje s tímto API serverem, když běží na různých portech?“ Skvělá otázka! To se dotýká něčeho, na co každý webový vývojář dříve či později narazí. > 🔒 **Bezpečnost mezi doménami**: Prohlížeče prosazují „politiku stejného původu“, aby zabránily neoprávněné komunikaci mezi různými doménami. Stejně jako kontrolní systém v Pentagonu ověřují, že komunikace je autorizovaná, než umožní přenos dat. > **V našem nastavení:** - Vaše webová aplikace běží na `localhost:3000` (vývojový server) - Váš API server běží na `localhost:5000` (backend server) - API server zahrnuje [CORS hlavičky](https://developer.mozilla.org/docs/Web/HTTP/CORS), které explicitně autorizují komunikaci z vaší webové aplikace Toto nastavení odráží reálný vývoj, kde frontendové a backendové aplikace obvykle běží na samostatných serverech. > 📚 **Další informace**: Prozkoumejte hlouběji API a získávání dat s tímto komplexním [Microsoft Learn modulem o API](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Oživení vašich dat v HTML Nyní uděláme získaná data viditelná pro uživatele prostřednictvím manipulace s DOM. Stejně jako proces vyvolávání fotografií v temné komoře, vezmeme neviditelná data a zobrazíme je tak, aby je uživatelé mohli vidět a interagovat s nimi. Manipulace s DOM je technika, která transformuje statické webové stránky na dynamické aplikace, které aktualizují svůj obsah na základě interakcí uživatelů a odpovědí serveru. ### Výběr správného nástroje pro práci Pokud jde o aktualizaci vašeho HTML pomocí JavaScriptu, máte několik možností. Představte si je jako různé nástroje v sadě nářadí – každý z nich je ideální pro konkrétní úkoly: | Metoda | Na co je skvělá | Kdy ji použít | Úroveň bezpečnosti | |--------|-----------------|---------------|--------------------| | `textContent` | Bezpečné zobrazování uživatelských dat | Kdykoli zobrazujete text | ✅ Spolehlivé | Pro složitější obsah zkombinujte [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) s metodou [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append): ```javascript // Safe way to create new elements const transactionItem = document.createElement('div'); transactionItem.className = 'transaction-item'; transactionItem.textContent = `${transaction.date}: ${transaction.description}`; container.append(transactionItem); ``` **Porozumění tomuto přístupu:** - **Vytváří** nové DOM prvky programově - **Umožňuje** plnou kontrolu nad atributy a obsahem prvků - **Podporuje** složité, vnořené struktury prvků - **Zajišťuje** bezpečnost oddělením struktury od obsahu > ⚠️ **Bezpečnostní úvaha**: I když [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) často figuruje v tutoriálech, může spouštět vložené skripty. Stejně jako bezpečnostní protokoly v CERNu zabraňují neoprávněnému spuštění kódu, použití `textContent` a `createElement` poskytuje bezpečnější alternativy. > **Rizika innerHTML:** - Spouští jakékoli `