# Paggawa ng Banking App Bahagi 3: Mga Paraan ng Pagkuha at Paggamit ng Data Isipin ang computer ng Enterprise sa Star Trek - kapag tinanong ni Captain Picard ang status ng barko, agad na lumalabas ang impormasyon nang hindi nasisira ang buong interface o muling binubuo ang sarili nito. Ang tuluy-tuloy na daloy ng impormasyon na iyon ang eksaktong ginagawa natin dito gamit ang dynamic na pagkuha ng data. Sa ngayon, ang iyong banking app ay parang isang naka-print na pahayagan - nagbibigay ng impormasyon ngunit static. Gagawin natin itong parang mission control sa NASA, kung saan tuluy-tuloy ang daloy ng data at nag-a-update nang real-time nang hindi naaabala ang workflow ng user. Matututo kang makipag-ugnayan sa mga server nang asynchronous, mag-handle ng data na dumarating sa iba't ibang oras, at gawing makabuluhan ang raw na impormasyon para sa iyong mga user. Ito ang pagkakaiba ng demo software sa production-ready software. ## Pre-Lecture Quiz [Pre-lecture quiz](https://ff-quizzes.netlify.app/web/quiz/45) ### Mga Kinakailangan Bago sumabak sa pagkuha ng data, tiyaking handa ka sa mga sumusunod na bahagi: - **Nakaraang Aralin**: Kumpletuhin ang [Login at Registration Form](../2-forms/README.md) - magpapatuloy tayo sa pundasyong ito - **Local Server**: I-install ang [Node.js](https://nodejs.org) at [patakbuhin ang server API](../api/README.md) para magbigay ng account data - **API Connection**: Subukan ang koneksyon ng iyong server gamit ang command na ito: ```bash curl http://localhost:5000/api # Expected response: "Bank API v1.0.0" ``` Ang mabilis na test na ito ay nagsisiguro na ang lahat ng bahagi ay maayos na nakikipag-ugnayan: - Tinitiyak na ang Node.js ay maayos na tumatakbo sa iyong sistema - Kinukumpirma na ang iyong API server ay aktibo at tumutugon - Pinapatunayan na ang iyong app ay maabot ang server (parang pag-check ng radio contact bago ang isang misyon) --- ## Pag-unawa sa Pagkuha ng Data sa Modernong Web Apps Ang paraan ng pag-handle ng data ng mga web application ay lubos na nagbago sa nakalipas na dalawang dekada. Ang pag-unawa sa ebolusyong ito ay makakatulong sa iyo na ma-appreciate kung bakit ang mga modernong teknolohiya tulad ng AJAX at Fetch API ay napakalakas at kung bakit sila naging mahalagang kasangkapan para sa mga web developer. Tuklasin natin kung paano gumagana ang mga tradisyunal na website kumpara sa mga dynamic at responsive na application na ginagawa natin ngayon. ### Tradisyunal na Multi-Page Applications (MPA) Sa mga unang araw ng web, bawat click ay parang pagpapalit ng channel sa lumang telebisyon - magbablanko ang screen, pagkatapos ay dahan-dahang magpapakita ng bagong content. Ganito ang realidad ng mga unang web application, kung saan bawat interaksyon ay nangangahulugan ng muling pagbubuo ng buong pahina mula sa simula. ```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) ```  **Bakit pakiramdam na clunky ang approach na ito:** - Bawat click ay nangangahulugan ng muling pagbubuo ng buong pahina mula sa simula - Ang mga user ay naaabala sa gitna ng kanilang iniisip dahil sa nakakainis na page flashes - Ang iyong internet connection ay nagtatrabaho nang sobra sa pag-download ng parehong header at footer nang paulit-ulit - Ang mga app ay parang pag-click sa filing cabinet kaysa sa paggamit ng software ### Modernong Single-Page Applications (SPA) Binago ng AJAX (Asynchronous JavaScript and XML) ang paradigm na ito nang buo. Tulad ng modular na disenyo ng International Space Station, kung saan maaaring palitan ng mga astronaut ang mga indibidwal na bahagi nang hindi muling binubuo ang buong istruktura, pinapayagan tayo ng AJAX na i-update ang mga partikular na bahagi ng webpage nang hindi nire-reload ang lahat. Kahit na binabanggit ng pangalan ang XML, kadalasan ay JSON ang ginagamit natin ngayon, ngunit nananatili ang pangunahing prinsipyo: i-update lamang ang kailangang baguhin. ```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) ```  **Bakit mas maganda ang pakiramdam ng SPAs:** - Ang mga bahagi lamang na talagang nagbago ang na-update (matalino, di ba?) - Wala nang nakakagulat na interruptions - nananatili ang mga user sa kanilang flow - Mas kaunting data ang dumadaan sa wire kaya mas mabilis ang pag-load - Ang lahat ay pakiramdam na snappy at responsive, tulad ng mga app sa iyong telepono ### Ang Ebolusyon sa Modernong Fetch API Nagbibigay ang mga modernong browser ng [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), na pumapalit sa mas lumang [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Tulad ng pagkakaiba ng paggamit ng telegrapo at email, ang Fetch API ay gumagamit ng promises para sa mas malinis na asynchronous na code at natural na hinahandle ang JSON. | Tampok | XMLHttpRequest | Fetch API | |-------|----------------|----------| | **Syntax** | Kumplikadong callback-based | Malinis na promise-based | | **JSON Handling** | Kinakailangan ang manual parsing | Built-in `.json()` method | | **Error Handling** | Limitadong impormasyon sa error | Komprehensibong detalye ng error | | **Modern Support** | Legacy compatibility | ES6+ promises at async/await | > 💡 **Browser Compatibility**: Magandang balita - gumagana ang Fetch API sa lahat ng modernong browser! Kung curious ka sa mga partikular na bersyon, [caniuse.com](https://caniuse.com/fetch) ang may kumpletong compatibility story. > **Ang bottom line:** - Gumagana nang mahusay sa Chrome, Firefox, Safari, at Edge (karamihan sa mga lugar kung nasaan ang iyong mga user) - Ang Internet Explorer lamang ang nangangailangan ng karagdagang tulong (at sa totoo lang, panahon na para bitawan ang IE) - Perpektong nakahanda para sa eleganteng async/await patterns na gagamitin natin mamaya ### Pagpapatupad ng User Login at Pagkuha ng Data Ngayon, ipapatupad natin ang login system na magbabago sa iyong banking app mula sa static na display patungo sa functional na application. Tulad ng mga authentication protocols na ginagamit sa mga secure na pasilidad ng militar, ivavalidate natin ang mga kredensyal ng user at pagkatapos ay magbibigay ng access sa kanilang partikular na data. Gagawin natin ito nang paunti-unti, simula sa basic authentication at pagkatapos ay idagdag ang mga kakayahan sa pagkuha ng data. #### Hakbang 1: Gumawa ng Pundasyon ng Login Function Buksan ang iyong `app.js` file at magdagdag ng bagong `login` function. Ito ang maghahandle ng proseso ng authentication ng user: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **I-breakdown natin ito:** - Ang `async` keyword? Sinasabi nito sa JavaScript "hey, maaaring kailanganin ng function na ito na maghintay para sa mga bagay" - Kinukuha natin ang form mula sa pahina (walang fancy, hinahanap lang ito gamit ang ID nito) - Pagkatapos ay kinukuha natin ang anumang tinype ng user bilang kanilang username - Narito ang isang neat na trick: maaari mong ma-access ang anumang form input gamit ang `name` attribute nito - walang kailangan para sa dagdag na getElementById calls! > 💡 **Form Access Pattern**: Ang bawat form control ay maaaring ma-access gamit ang name (itinakda sa HTML gamit ang `name` attribute) bilang property ng form element. Nagbibigay ito ng malinis at nababasang paraan para makuha ang data ng form. #### Hakbang 2: Gumawa ng Account Data Fetching Function Susunod, gagawa tayo ng dedicated function para kunin ang account data mula sa server. Sinusunod nito ang parehong pattern ng iyong registration function ngunit nakatuon sa pagkuha ng data: ```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' }; } } ``` **Narito ang nagagawa ng code na ito:** - **Ginagamit** ang modernong `fetch` API para mag-request ng data nang asynchronous - **Gumagawa** ng GET request URL gamit ang username parameter - **Ina-apply** ang `encodeURIComponent()` para ligtas na ma-handle ang special characters sa URLs - **Kinoconvert** ang response sa JSON format para sa madaling data manipulation - **Hinahandle** ang errors nang maayos sa pamamagitan ng pagbabalik ng error object sa halip na mag-crash > ⚠️ **Security Note**: Ang `encodeURIComponent()` function ay nagha-handle ng special characters sa URLs. Tulad ng encoding systems na ginagamit sa naval communications, tinitiyak nito na ang iyong mensahe ay darating nang eksakto kung paano ito nilayon, pinipigilan ang mga character tulad ng "#" o "&" na ma-misinterpret. > **Bakit ito mahalaga:** - Pinipigilan ang special characters na masira ang URLs - Pinoprotektahan laban sa URL manipulation attacks - Tinitiyak na ang iyong server ay makakatanggap ng intended data - Sumusunod sa secure coding practices #### Pag-unawa sa HTTP GET Requests Narito ang isang bagay na maaaring magulat ka: kapag ginamit mo ang `fetch` nang walang anumang dagdag na options, awtomatikong gumagawa ito ng [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) request. Perpekto ito para sa ginagawa natin - humihiling sa server "hey, maaari ko bang makita ang account data ng user na ito?" Isipin ang GET requests na parang magalang na paghingi ng libro sa library - humihiling ka na makita ang isang bagay na umiiral na. Ang POST requests (na ginamit natin para sa registration) ay mas parang pagsusumite ng bagong libro para idagdag sa koleksyon. | GET Request | POST Request | |-------------|-------------| | **Layunin** | Kunin ang umiiral na data | Magpadala ng bagong data sa server | | **Parameters** | Sa URL path/query string | Sa request body | | **Caching** | Maaaring i-cache ng mga browser | Hindi karaniwang naka-cache | | **Seguridad** | Nakikita sa URL/logs | Nakatago sa request body | #### Hakbang 3: Pagsasama-sama ng Lahat Ngayon para sa nakaka-satisfy na bahagi - ikonekta natin ang iyong account fetching function sa login process. Dito nagkakaroon ng koneksyon ang lahat: ```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'); } ``` Ang function na ito ay sumusunod sa malinaw na sequence: - Kunin ang username mula sa form input - Humiling ng account data ng user mula sa server - I-handle ang anumang errors na mangyayari sa proseso - I-store ang account data at mag-navigate sa dashboard kapag tagumpay > 🎯 **Async/Await Pattern**: Dahil ang `getAccount` ay isang asynchronous function, ginagamit natin ang `await` keyword para i-pause ang execution hanggang sa tumugon ang server. Pinipigilan nito ang code na magpatuloy nang may undefined na data. #### Hakbang 4: Gumawa ng Tahanan para sa Iyong Data Kailangan ng iyong app ng lugar para maalala ang impormasyon ng account kapag na-load na ito. Isipin ito na parang short-term memory ng iyong app - isang lugar para panatilihing handy ang data ng kasalukuyang user. Magdagdag ng linyang ito sa itaas ng iyong `app.js` file: ```javascript // This holds the current user's account data let account = null; ``` **Bakit natin ito kailangan:** - Pinapanatili ang account data na accessible mula sa kahit saan sa iyong app - Ang pagsisimula sa `null` ay nangangahulugang "wala pang naka-login" - Ina-update kapag may matagumpay na nag-login o nag-register - Kumilos bilang isang single source of truth - walang kalituhan kung sino ang naka-login #### Hakbang 5: I-wire Up ang Iyong Form Ngayon, ikonekta natin ang iyong bagong login function sa iyong HTML form. I-update ang iyong form tag nang ganito: ```html
``` **Ano ang ginagawa ng maliit na pagbabago na ito:** - Pinipigilan ang form na gawin ang default nitong "i-reload ang buong pahina" na behavior - Tinatawag ang iyong custom na JavaScript function sa halip - Pinapanatili ang lahat na smooth at single-page-app-like - Binibigyan ka ng kumpletong kontrol sa kung ano ang mangyayari kapag pinindot ng mga user ang "Login" #### Hakbang 6: Pagandahin ang Iyong Registration Function Para sa consistency, i-update ang iyong `register` function para rin mag-store ng account data at mag-navigate sa dashboard: ```javascript // Add these lines at the end of your register function account = result; navigate('/dashboard'); ``` **Ang enhancement na ito ay nagbibigay:** - **Seamless** na transition mula sa registration patungo sa dashboard - **Consistent** na user experience sa pagitan ng login at registration flows - **Immediate** na access sa account data pagkatapos ng matagumpay na registration #### Pagsubok sa Iyong Implementasyon ```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] ``` **Panahon na para subukan ito:** 1. Gumawa ng bagong account para tiyaking gumagana ang lahat 2. Subukang mag-login gamit ang parehong credentials 3. Silipin ang console ng iyong browser (F12) kung may tila hindi tama 4. Tiyaking napupunta ka sa dashboard pagkatapos ng matagumpay na login Kung may hindi gumagana, huwag mag-panic! Karamihan sa mga isyu ay simpleng ayusin tulad ng typos o pagkalimot na i-start ang API server. #### Isang Mabilis na Salita Tungkol sa Cross-Origin Magic Maaaring iniisip mo: "Paano nakikipag-usap ang aking web app sa API server na tumatakbo sa iba't ibang ports?" Magandang tanong! Ito ay tumutukoy sa isang bagay na bawat web developer ay natutuklasan kalaunan. > 🔒 **Cross-Origin Security**: Ang mga browser ay nagpapatupad ng "same-origin policy" upang maiwasan ang hindi awtorisadong komunikasyon sa pagitan ng iba't ibang domain. Tulad ng checkpoint system sa Pentagon, tinitiyak nila na ang komunikasyon ay awtorisado bago payagan ang paglipat ng data. > **Sa ating setup:** - Ang iyong web app ay tumatakbo sa `localhost:3000` (development server) - Ang iyong API server ay tumatakbo sa `localhost:5000` (backend server) - Ang API server ay naglalaman ng [CORS headers](https://developer.mozilla.org/docs/Web/HTTP/CORS) na tahasang nagbibigay awtorisasyon sa komunikasyon mula sa iyong web app Ang configuration na ito ay sumasalamin sa real-world development kung saan ang frontend at backend applications ay karaniwang tumatakbo sa magkahiwalay na server. > 📚 **Matuto Pa**: Tuklasin ang higit pa tungkol sa APIs at pagkuha ng data gamit ang komprehensibong [Microsoft Learn module on APIs](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Pagdadala ng Iyong Data sa Buhay sa HTML Ngayon, gagawin nating visible sa mga user ang nakuha na data sa pamamagitan ng DOM manipulation. Tulad ng proseso ng pag-develop ng mga litrato sa darkroom, kinukuha natin ang invisible na data at nire-render ito sa isang bagay na makikita at ma-interact ng mga user. Ang DOM manipulation ay ang teknik na nagbabago sa static na mga web page patungo sa mga dynamic na application na nag-a-update ng kanilang content base sa interaksyon ng user at tugon ng server. ### Pagpili ng Tamang Kasangkapan para sa Trabaho Kapag nag-a-update ng iyong HTML gamit ang JavaScript, mayroon kang ilang mga opsyon. Isipin ang mga ito na parang iba't ibang tools sa toolbox - bawat isa ay perpekto para sa partikular na trabaho: | Paraan | Para saan ito magaling | Kailan ito gagamitin | Antas ng Kaligtasan | |--------|------------------------|---------------------|---------------------| | `textContent` | Pagpapakita ng user data nang ligtas | Anumang oras na nagpapakita ng text | ✅ Rock solid | | `createElement()` + `append()` | Pagbuo ng complex na layout | Paglikha ng bagong sections/lists | ✅ Bulletproof | | `innerHTML` | Pag-set ng HTML content | ⚠️ Subukang iwasan ito | ❌ Risky business | #### Ang Ligtas na Paraan para Magpakita ng Text: textContent Ang [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) property ay ang iyong pinakamahusay na kaibigan kapag nagpapakita ng user data. Parang may bouncer para sa iyong webpage - walang mapanganib na makakapasok: ```javascript // The safe, reliable way to update text const balanceElement = document.getElementById('balance'); balanceElement.textContent = account.balance; ``` **Mga Benepisyo ng textContent:** - Tinuturing ang lahat bilang plain text (pinipigilan ang script execution) - Awtomatikong nililinis ang existing content - Epektibo para sa simpleng text updates - Nagbibigay ng built-in na seguridad laban sa malicious content #### Paglikha ng Dynamic na HTML Elements Para sa mas kumplikadong nilalaman, pagsamahin ang [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) sa [`append()`](https://developer.mozilla.org/docs/Web/API/ParentNode/append) na pamamaraan: ```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); ``` **Pag-unawa sa pamamaraang ito:** - **Lumilikha** ng mga bagong elemento ng DOM nang programmatically - **Nagbibigay** ng ganap na kontrol sa mga katangian at nilalaman ng elemento - **Nagpapahintulot** ng masalimuot, nested na istruktura ng elemento - **Pinapanatili** ang seguridad sa pamamagitan ng paghihiwalay ng istruktura mula sa nilalaman > ⚠️ **Pagsasaalang-alang sa Seguridad**: Bagama't ang [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) ay madalas na lumalabas sa mga tutorial, maaari itong magpatupad ng mga naka-embed na script. Tulad ng mga protocol sa seguridad sa CERN na pumipigil sa hindi awtorisadong pagpapatupad ng code, ang paggamit ng `textContent` at `createElement` ay nagbibigay ng mas ligtas na alternatibo. > **Mga panganib ng innerHTML:** - Pinapatupad ang anumang `