# Sukurkite bankinę programėlę 3 dalis: Duomenų gavimo ir naudojimo metodai ## Klausimynas prieš paskaitą [Klausimynas prieš paskaitą](https://ff-quizzes.netlify.app/web/quiz/45) ### Įvadas Kiekvienos internetinės programėlės pagrindas yra *duomenys*. Duomenys gali būti įvairių formų, tačiau jų pagrindinis tikslas visada yra pateikti informaciją vartotojui. Kadangi internetinės programėlės tampa vis interaktyvesnės ir sudėtingesnės, tai, kaip vartotojas pasiekia ir sąveikauja su informacija, tampa esmine interneto kūrimo dalimi. Šioje pamokoje pamatysime, kaip asinchroniškai gauti duomenis iš serverio ir naudoti juos informacijai pateikti interneto puslapyje, neperkraunant HTML. ### Būtinos žinios Prieš pradedant šią pamoką, turite būti sukūrę [Prisijungimo ir registracijos formą](../2-forms/README.md) kaip dalį internetinės programėlės. Taip pat turite įdiegti [Node.js](https://nodejs.org) ir [paleisti serverio API](../api/README.md) lokaliai, kad galėtumėte gauti paskyros duomenis. Galite patikrinti, ar serveris veikia tinkamai, vykdydami šią komandą terminale: ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## AJAX ir duomenų gavimas Tradicinės interneto svetainės atnaujina rodomą turinį, kai vartotojas pasirenka nuorodą arba pateikia duomenis naudodamas formą, perkraudamos visą HTML puslapį. Kiekvieną kartą, kai reikia įkelti naujus duomenis, interneto serveris grąžina visiškai naują HTML puslapį, kurį naršyklė turi apdoroti, nutraukdama dabartinį vartotojo veiksmą ir apribodama sąveiką per įkrovimą. Šis darbo procesas taip pat vadinamas *daugiapuslapių programėlių* arba *MPA*.  Kai internetinės programėlės pradėjo tapti sudėtingesnės ir interaktyvesnės, atsirado nauja technika, vadinama [AJAX (Asinchroninis JavaScript ir XML)](https://en.wikipedia.org/wiki/Ajax_(programming)). Ši technika leidžia internetinėms programėlėms siųsti ir gauti duomenis iš serverio asinchroniškai naudojant JavaScript, neperkraunant HTML puslapio, todėl atnaujinimai vyksta greičiau, o vartotojo sąveika tampa sklandesnė. Kai nauji duomenys gaunami iš serverio, dabartinis HTML puslapis taip pat gali būti atnaujintas naudojant [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model) API. Laikui bėgant, šis požiūris išsivystė į tai, kas dabar vadinama [*vieno puslapio programėle* arba *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  Kai AJAX buvo pirmą kartą pristatytas, vienintelė API, leidžianti asinchroniškai gauti duomenis, buvo [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Tačiau šiuolaikinės naršyklės dabar taip pat įgyvendina patogesnę ir galingesnę [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), kuri naudoja pažadus ir yra geriau pritaikyta manipuliuoti JSON duomenimis. > Nors visos šiuolaikinės naršyklės palaiko `Fetch API`, jei norite, kad jūsų internetinė programėlė veiktų senesnėse naršyklėse, visada verta pirmiausia patikrinti [suderinamumo lentelę caniuse.com](https://caniuse.com/fetch). ### Užduotis [Ankstesnėje pamokoje](../2-forms/README.md) įgyvendinome registracijos formą paskyrai sukurti. Dabar pridėsime kodą, kad galėtume prisijungti naudojant esamą paskyrą ir gauti jos duomenis. Atidarykite `app.js` failą ir pridėkite naują `login` funkciją: ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; } ``` Čia pradedame nuo formos elemento gavimo naudojant `getElementById()`, o tada gauname vartotojo vardą iš įvesties su `loginForm.user.value`. Kiekvieną formos valdiklį galima pasiekti pagal jo pavadinimą (nustatytą HTML naudojant `name` atributą) kaip formos savybę. Panašiai kaip darėme registracijai, sukursime kitą funkciją, skirtą serverio užklausai atlikti, tačiau šį kartą duomenims gauti: ```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' }; } } ``` Naudojame `fetch` API, kad asinchroniškai užklaustume duomenis iš serverio, tačiau šį kartą mums nereikia jokių papildomų parametrų, išskyrus URL, kurį reikia iškviesti, nes mes tik užklausome duomenis. Pagal numatymą, `fetch` sukuria [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET) HTTP užklausą, kurios mes čia siekiame. ✅ `encodeURIComponent()` yra funkcija, kuri užkoduoja specialius simbolius URL. Kokias problemas galėtume turėti, jei nenaudotume šios funkcijos ir tiesiogiai naudotume `user` reikšmę URL? Dabar atnaujinkime mūsų `login` funkciją, kad ji naudotų `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'); } ``` Pirma, kadangi `getAccount` yra asinchroninė funkcija, turime ją suderinti su `await` raktažodžiu, kad lauktume serverio rezultato. Kaip ir bet kurioje serverio užklausoje, taip pat turime spręsti klaidų atvejus. Kol kas pridėsime tik žurnalo pranešimą, kad būtų rodomos klaidos, ir vėliau grįšime prie to. Tada turime išsaugoti duomenis kažkur, kad vėliau galėtume juos naudoti informacijos pateikimui prietaisų skydelyje. Kadangi `account` kintamasis dar neegzistuoja, sukursime globalų kintamąjį failo viršuje: ```js let account = null; ``` Kai vartotojo duomenys išsaugomi kintamajame, galime pereiti nuo *prisijungimo* puslapio prie *prietaisų skydelio* naudodami jau turimą `navigate()` funkciją. Galiausiai, turime iškviesti mūsų `login` funkciją, kai prisijungimo forma pateikiama, modifikuodami HTML: ```html