# Jenga App ya Benki Sehemu ya 3: Njia za Kupata na Kutumia Data Fikiria kompyuta ya Enterprise katika Star Trek - wakati Kapteni Picard anauliza hali ya meli, taarifa zinaonekana mara moja bila kiolesura kizima kuzima na kujijenga upya. Mtiririko huo wa taarifa bila kukwama ndio tunalenga kujenga hapa kwa kutumia mbinu za kupata data kwa njia ya nguvu. Kwa sasa, app yako ya benki ni kama gazeti lililochapishwa - lina taarifa lakini ni tuli. Tutalibadilisha kuwa kitu kama kituo cha udhibiti cha NASA, ambapo data inapita bila kukoma na inasasishwa kwa muda halisi bila kuingilia mtiririko wa kazi wa mtumiaji. Utajifunza jinsi ya kuwasiliana na seva kwa njia ya asynchronous, kushughulikia data inayofika kwa nyakati tofauti, na kubadilisha taarifa ghafi kuwa kitu cha maana kwa watumiaji wako. Hii ni tofauti kati ya demo na programu inayofaa kwa uzalishaji. ## Maswali ya Awali ya Somo [Maswali ya awali ya somo](https://ff-quizzes.netlify.app/web/quiz/45) ### Mahitaji ya Awali Kabla ya kuanza kupata data, hakikisha una vipengele hivi tayari: - **Somo la Awali**: Kamilisha [Fomu ya Kuingia na Usajili](../2-forms/README.md) - tutajenga juu ya msingi huu - **Seva ya Ndani**: Sakinisha [Node.js](https://nodejs.org) na [endesha API ya seva](../api/README.md) ili kutoa data ya akaunti - **Muunganisho wa API**: Jaribu muunganisho wa seva yako kwa amri hii: ```bash curl http://localhost:5000/api # Expected response: "Bank API v1.0.0" ``` Jaribio hili la haraka linahakikisha vipengele vyote vinawasiliana vizuri: - Inathibitisha kuwa Node.js inaendesha vizuri kwenye mfumo wako - Inathibitisha kuwa seva yako ya API iko hai na inajibu - Inathibitisha kuwa app yako inaweza kufikia seva (kama kuangalia mawasiliano ya redio kabla ya misheni) --- ## Kuelewa Upatikanaji wa Data katika Programu za Kisasa za Wavuti Njia ambayo programu za wavuti zinashughulikia data imebadilika sana katika miongo miwili iliyopita. Kuelewa mabadiliko haya kutakusaidia kuthamini kwa nini mbinu za kisasa kama AJAX na Fetch API ni zenye nguvu na kwa nini zimekuwa zana muhimu kwa watengenezaji wa wavuti. Hebu tuchunguze jinsi tovuti za jadi zilivyofanya kazi ikilinganishwa na programu za kisasa, zinazojibika tunazojenga leo. ### Programu za Jadi za Kurasa Nyingi (MPA) Katika siku za mwanzo za wavuti, kila kubofya kulikuwa kama kubadilisha chaneli kwenye televisheni ya zamani - skrini ingekuwa tupu, kisha polepole kuonyesha maudhui mapya. Hii ilikuwa hali halisi ya programu za wavuti za awali, ambapo kila mwingiliano ulimaanisha kujenga upya ukurasa mzima kutoka mwanzo. ```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) ``` ![Mtiririko wa sasisho katika programu ya kurasa nyingi](../../../../translated_images/mpa.7f7375a1a2d4aa779d3f928a2aaaf9ad76bcdeb05cfce2dc27ab126024050f51.sw.png) **Kwa nini mbinu hii ilihisi kuwa na matatizo:** - Kila kubofya kulimaanisha kujenga upya ukurasa mzima kutoka mwanzo - Watumiaji walikatizwa mawazo yao na miale ya kurasa zinazojirudia - Muunganisho wako wa intaneti ulifanya kazi kupita kiasi kupakua kichwa na footer mara kwa mara - Programu zilihisi kama kubofya kupitia kabati la faili badala ya kutumia programu ### Programu za Kisasa za Ukurasa Mmoja (SPA) AJAX (Asynchronous JavaScript and XML) ilibadilisha kabisa dhana hii. Kama muundo wa moduli wa Kituo cha Kimataifa cha Anga, ambapo wanaanga wanaweza kubadilisha vipengele vya mtu binafsi bila kujenga upya muundo mzima, AJAX inatuwezesha kusasisha sehemu maalum za ukurasa wa wavuti bila kupakia upya kila kitu. Ingawa jina linataja XML, tunatumia JSON zaidi leo, lakini kanuni ya msingi inabaki: sasisha tu kile kinachohitaji kubadilika. ```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) ``` ![Mtiririko wa sasisho katika programu ya ukurasa mmoja](../../../../translated_images/spa.268ec73b41f992c2a21ef9294235c6ae597b3c37e2c03f0494c2d8857325cc57.sw.png) **Kwa nini SPA zinahisi kuwa bora zaidi:** - Sehemu tu ambazo zimebadilika ndizo zinazosasishwa (ni akili, sivyo?) - Hakuna tena usumbufu wa ghafla - watumiaji wako wanabaki katika mtiririko wao - Data kidogo inayosafiri kwenye waya inamaanisha kupakia haraka - Kila kitu kinahisi kuwa haraka na kujibika, kama programu kwenye simu yako ### Mageuzi hadi Fetch API ya Kisasa Vivinjari vya kisasa vinatoa [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), ambayo inachukua nafasi ya [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Kama tofauti kati ya kutumia telegrafu na barua pepe, Fetch API hutumia ahadi kwa msimbo safi wa asynchronous na hushughulikia JSON kwa urahisi. | Kipengele | XMLHttpRequest | Fetch API | |-----------|----------------|-----------| | **Sintaksia** | Msingi wa callback ngumu | Msingi wa ahadi safi | | **Ushughulikiaji wa JSON** | Inahitaji uchambuzi wa mwongozo | Njia ya kujengwa `.json()` | | **Ushughulikiaji wa Makosa** | Taarifa ndogo za makosa | Maelezo kamili ya makosa | | **Msaada wa Kisasa** | Ulinganifu wa urithi | Ahadi za ES6+ na async/await | > 💡 **Ulinganifu wa Vivinjari**: Habari njema - Fetch API inafanya kazi katika vivinjari vyote vya kisasa! Ikiwa unataka kujua kuhusu matoleo maalum, [caniuse.com](https://caniuse.com/fetch) ina hadithi kamili ya ulinganifu. > **Hitimisho:** - Inafanya kazi vizuri katika Chrome, Firefox, Safari, na Edge (kimsingi kila mahali watumiaji wako walipo) - Internet Explorer pekee inahitaji msaada wa ziada (na kwa kweli, ni wakati wa kuachana na IE) - Inakuweka tayari kwa mifumo maridadi ya async/await tutakayotumia baadaye ### Kutekeleza Mfumo wa Kuingia na Upatikanaji wa Data Sasa hebu tuelekeze mfumo wa kuingia ambao unabadilisha app yako ya benki kutoka onyesho tuli hadi programu inayofanya kazi. Kama itifaki za uthibitishaji zinazotumika katika vituo vya kijeshi salama, tutathibitisha sifa za mtumiaji na kisha kutoa ufikiaji wa data yao maalum. Tutajenga hili hatua kwa hatua, kuanzia na uthibitishaji wa msingi na kisha kuongeza uwezo wa kupata data. #### Hatua ya 1: Unda Msingi wa Kazi ya Kuingia Fungua faili yako ya `app.js` na ongeza kazi mpya ya `login`. Hii itashughulikia mchakato wa uthibitishaji wa mtumiaji: ```javascript async function login() { const loginForm = document.getElementById('loginForm'); const user = loginForm.user.value; } ``` **Hebu tuchambue hili:** - Neno `async`? Linaiambia JavaScript "hey, kazi hii inaweza kuhitaji kusubiri mambo" - Tunachukua fomu yetu kutoka kwenye ukurasa (sio kitu cha kifahari, tunaitafuta kwa ID yake) - Kisha tunachukua chochote ambacho mtumiaji ameandika kama jina la mtumiaji - Hii ni mbinu nzuri: unaweza kufikia pembejeo yoyote ya fomu kwa sifa yake ya `name` - hakuna haja ya kupiga simu za ziada za getElementById! > 💡 **Mfumo wa Ufikiaji wa Fomu**: Kila udhibiti wa fomu unaweza kufikiwa kwa jina lake (lililowekwa kwenye HTML kwa kutumia sifa ya `name`) kama mali ya kipengele cha fomu. Hii inatoa njia safi, inayosomeka ya kupata data ya fomu. #### Hatua ya 2: Unda Kazi ya Kupata Data ya Akaunti Kisha, tutaunda kazi maalum ya kupata data ya akaunti kutoka kwa seva. Hii inafuata mtindo sawa na kazi yako ya usajili lakini inazingatia upatikanaji wa 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' }; } } ``` **Hii inachokamilisha:** - **Inatumia** Fetch API ya kisasa kuomba data kwa njia ya asynchronous - **Inajenga** URL ya ombi la GET na parameter ya jina la mtumiaji - **Inatumia** `encodeURIComponent()` kushughulikia kwa usalama herufi maalum kwenye URL - **Inabadilisha** majibu kuwa muundo wa JSON kwa urahisi wa kudhibiti data - **Inashughulikia** makosa kwa ustadi kwa kurudisha kitu cha makosa badala ya kuanguka > ⚠️ **Kumbuka Usalama**: Kazi ya `encodeURIComponent()` hushughulikia herufi maalum kwenye URL. Kama mifumo ya usimbaji inayotumika katika mawasiliano ya majini, inahakikisha ujumbe wako unafika kama ulivyokusudiwa, kuzuia herufi kama "#" au "&" kutafsiriwa vibaya. > **Kwa nini hili ni muhimu:** - Huzuia herufi maalum kuvunja URL - Hulinda dhidi ya mashambulizi ya kudanganya URL - Inahakikisha seva yako inapokea data iliyokusudiwa - Inafuata mazoea salama ya usimbaji #### Kuelewa Maombi ya HTTP GET Hili linaweza kukushangaza: unapoitumia `fetch` bila chaguo lolote la ziada, inaunda moja kwa moja ombi la [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET). Hii ni kamili kwa tunachofanya - kuuliza seva "hey, naweza kuona data ya akaunti ya mtumiaji huyu?" Fikiria maombi ya GET kama kuomba kwa heshima kukopa kitabu kutoka maktaba - unaomba kuona kitu ambacho tayari kipo. Maombi ya POST (ambayo tulitumia kwa usajili) ni zaidi kama kuwasilisha kitabu kipya ili kiongezwe kwenye mkusanyiko. | Ombi la GET | Ombi la POST | |-------------|-------------| | **Madhumuni** | Kupata data iliyopo | Kutuma data mpya kwa seva | | **Vigezo** | Katika njia ya URL/nyuzi ya swali | Katika mwili wa ombi | | **Uwekaji Akiba** | Inaweza kuwekwa akiba na vivinjari | Sio kawaida kuwekwa akiba | | **Usalama** | Inaonekana kwenye URL/kumbukumbu | Imefichwa kwenye mwili wa ombi | #### Hatua ya 3: Kuunganisha Yote Pamoja Sasa kwa sehemu ya kuridhisha - hebu tuunganishe kazi yako ya kupata akaunti na mchakato wa kuingia. Hapa ndipo kila kitu kinapokamilika: ```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'); } ``` Kazi hii inafuata mlolongo wazi: - Chukua jina la mtumiaji kutoka pembejeo ya fomu - Omba data ya akaunti ya mtumiaji kutoka kwa seva - Shughulikia makosa yoyote yanayotokea wakati wa mchakato - Hifadhi data ya akaunti na nenda kwenye dashibodi baada ya mafanikio > 🎯 **Mfumo wa Async/Await**: Kwa kuwa `getAccount` ni kazi ya asynchronous, tunatumia neno `await` kusimamisha utekelezaji hadi seva itakapojibu. Hii huzuia msimbo kuendelea na data isiyojulikana. #### Hatua ya 4: Unda Sehemu ya Kuhifadhi Data Yako App yako inahitaji mahali pa kukumbuka taarifa za akaunti mara tu inapopakuliwa. Fikiria hii kama kumbukumbu ya muda mfupi ya app yako - mahali pa kuweka data ya mtumiaji wa sasa karibu. Ongeza mstari huu juu ya faili yako ya `app.js`: ```javascript // This holds the current user's account data let account = null; ``` **Kwa nini tunahitaji hili:** - Inahifadhi data ya akaunti inayoweza kufikiwa kutoka popote kwenye app yako - Kuanza na `null` kunamaanisha "hakuna mtu aliyeingia bado" - Inasasishwa wakati mtu anaingia au anasajiliwa kwa mafanikio - Inafanya kazi kama chanzo kimoja cha ukweli - hakuna mkanganyiko kuhusu nani aliyeingia #### Hatua ya 5: Unganisha Fomu Yako Sasa hebu tuunganishe kazi yako mpya ya kuingia na fomu yako ya HTML. Sasisha tagi ya fomu yako kama hii: ```html
``` **Kile mabadiliko haya madogo yanayofanya:** - Inazuia fomu kufanya tabia yake ya default ya "kupakia upya ukurasa mzima" - Inaita kazi yako maalum ya JavaScript badala yake - Inahakikisha kila kitu kinakuwa laini na kama programu ya ukurasa mmoja - Inakupa udhibiti kamili juu ya kinachotokea wakati watumiaji wanapobofya "Ingia" #### Hatua ya 6: Boresha Kazi Yako ya Usajili Kwa uthabiti, sasisha kazi yako ya `register` ili pia kuhifadhi data ya akaunti na kwenda kwenye dashibodi: ```javascript // Add these lines at the end of your register function account = result; navigate('/dashboard'); ``` **Uboreshaji huu unatoa:** - **Mpito laini** kutoka usajili hadi dashibodi - **Uzoefu thabiti** wa mtumiaji kati ya mtiririko wa kuingia na usajili - **Ufikiaji wa haraka** wa data ya akaunti baada ya usajili wa mafanikio #### Kupima Utekelezaji Wako ```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] ``` **Ni wakati wa kujaribu:** 1. Unda akaunti mpya ili kuhakikisha kila kitu kinafanya kazi 2. Jaribu kuingia kwa kutumia sifa hizo hizo 3. Angalia console ya kivinjari chako (F12) ikiwa kuna kitu kinachohisi kuwa na kasoro 4. Hakikisha unafika kwenye dashibodi baada ya kuingia kwa mafanikio Ikiwa kuna kitu hakifanyi kazi, usiwe na wasiwasi! Masuala mengi ni marekebisho rahisi kama makosa ya herufi au kusahau kuwasha seva ya API. #### Neno Fupi Kuhusu Uchawi wa Cross-Origin Unaweza kuwa unajiuliza: "Je, app yangu ya wavuti inazungumza na seva hii ya API wakati zinaendesha kwenye port tofauti?" Swali zuri! Hili linagusa kitu ambacho kila mtengenezaji wa wavuti hukutana nacho hatimaye. > 🔒 **Usalama wa Cross-Origin**: Vivinjari vinazingatia "sera ya asili sawa" ili kuzuia mawasiliano yasiyoidhinishwa kati ya vikoa tofauti. Kama mfumo wa ukaguzi katika Pentagon, wanathibitisha kuwa mawasiliano yameidhinishwa kabla ya kuruhusu uhamisho wa data. > **Katika usanidi wetu:** - App yako ya wavuti inaendesha kwenye `localhost:3000` (seva ya maendeleo) - Seva yako ya API inaendesha kwenye `localhost:5000` (seva ya backend) - Seva ya API inajumuisha vichwa vya [CORS](https://developer.mozilla.org/docs/Web/HTTP/CORS) vinavyoruhusu mawasiliano kutoka kwa app yako ya wavuti Usanidi huu unafanana na maendeleo ya ulimwengu halisi ambapo programu za mbele na nyuma kawaida huendesha kwenye seva tofauti. > 📚 **Jifunze Zaidi**: Chunguza kwa kina API na upatikanaji wa data kupitia moduli hii kamili ya [Microsoft Learn kuhusu API](https://docs.microsoft.com/learn/modules/use-apis-discover-museum-art/?WT.mc_id=academic-77807-sagibbon). ## Kuleta Data Yako Hai katika HTML Sasa tutafanya data iliyopatikana ionekane kwa watumiaji kupitia udanganyifu wa DOM. Kama mchakato wa kuendeleza picha katika chumba cha giza, tunachukua data isiyoonekana na kuifanya kuwa kitu ambacho watumiaji wanaweza kuona na kuingiliana nacho. Udanganyifu wa DOM ni mbinu inayobadilisha kurasa za wavuti tuli kuwa programu za nguvu zinazosasisha maudhui yao kulingana na mwingiliano wa mtumiaji na majibu ya seva. ### Kuchagua Zana Sahihi kwa Kazi Linapokuja suala la kusasisha HTML yako kwa JavaScript, una chaguo kadhaa. Fikiria hizi kama zana tofauti kwenye sanduku la zana - kila moja ni kamili kwa kazi maalum: | Njia | Inachofaa | Wakati wa kuitumia | Kiwango cha usalama | |------|-----------|--------------------|---------------------| | `textContent` | Kuonyesha data ya mtumiaji kwa usalama | Wakati wowote unapoonyesha maandishi | ✅ Salama kabisa | | `createElement()` + `append()` | Kujenga miundo tata | Kuunda sehemu mpya/orodha | ✅ Salama kabisa | | `innerHTML` | Kuweka maudhui ya HTML | ⚠️ Jaribu kuepuka hii | ❌ Hatari | #### Njia Salama ya Kuonyesha Maandishi: textContent Sifa ya [`textContent`](https://developer.mozilla.org/docs/Web/API/Node/textContent) ni rafiki yako bora unaponyesha data ya mtumiaji. Ni kama kuwa na mlinzi wa lango kwa wavuti yako - hakuna kitu hatari kinachopita: ```javascript // The safe, reliable way to update text const balanceElement = document.getElementById('balance'); balanceElement.textContent = account.balance; ``` **Faida za textContent:** - Inachukulia kila kitu kama maandishi ya kawaida (inazuia utekelezaji wa script) - Inafuta maudhui yaliyopo moja kwa moja - Inafaa kwa sasisho rahisi za maandishi Kwa maudhui changamano zaidi, changanya [`document.createElement()`](https://developer.mozilla.org/docs/Web/API/Document/createElement) na njia ya [`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); ``` **Kuelewa mbinu hii:** - **Inaunda** vipengele vipya vya DOM kwa njia ya programu - **Inadhibiti** kikamilifu sifa za vipengele na maudhui - **Inaruhusu** miundo changamano ya vipengele vilivyopachikana - **Inahifadhi** usalama kwa kutenganisha muundo na maudhui > ⚠️ **Tahadhari ya Usalama**: Ingawa [`innerHTML`](https://developer.mozilla.org/docs/Web/API/Element/innerHTML) inaonekana katika mafunzo mengi, inaweza kutekeleza maandishi yaliyopachikwa. Kama itifaki za usalama za CERN zinazozuia utekelezaji wa msimbo usioidhinishwa, kutumia `textContent` na `createElement` hutoa mbadala salama zaidi. > **Hatari za innerHTML:** - Hutekeleza maandishi yoyote ya `