# Costruire un'app bancaria Parte 3: Metodi per recuperare e utilizzare i dati ## Quiz Pre-Lezione [Quiz pre-lezione](https://ff-quizzes.netlify.app/web/quiz/45) ### Introduzione Al centro di ogni applicazione web c'è *il dato*. I dati possono assumere molte forme, ma il loro scopo principale è sempre quello di mostrare informazioni all'utente. Con le app web che diventano sempre più interattive e complesse, il modo in cui l'utente accede e interagisce con le informazioni è ora una parte fondamentale dello sviluppo web. In questa lezione, vedremo come recuperare dati da un server in modo asincrono e utilizzare questi dati per mostrare informazioni su una pagina web senza ricaricare l'HTML. ### Prerequisiti È necessario aver costruito la parte [Modulo di Login e Registrazione](../2-forms/README.md) dell'app web per questa lezione. Inoltre, è necessario installare [Node.js](https://nodejs.org) e [eseguire l'API del server](../api/README.md) localmente per ottenere i dati dell'account. Puoi verificare che il server stia funzionando correttamente eseguendo questo comando in un terminale: ```sh curl http://localhost:5000/api # -> should return "Bank API v1.0.0" as a result ``` --- ## AJAX e recupero dei dati I siti web tradizionali aggiornano il contenuto mostrato quando l'utente seleziona un link o invia dati tramite un modulo, ricaricando l'intera pagina HTML. Ogni volta che è necessario caricare nuovi dati, il server web restituisce una nuova pagina HTML che deve essere elaborata dal browser, interrompendo l'azione corrente dell'utente e limitando le interazioni durante il caricamento. Questo flusso di lavoro è anche chiamato *Applicazione Multi-Pagina* o *MPA*.  Quando le applicazioni web hanno iniziato a diventare più complesse e interattive, è emersa una nuova tecnica chiamata [AJAX (JavaScript e XML Asincrono)](https://en.wikipedia.org/wiki/Ajax_(programming)). Questa tecnica consente alle app web di inviare e recuperare dati da un server in modo asincrono utilizzando JavaScript, senza dover ricaricare la pagina HTML, risultando in aggiornamenti più rapidi e interazioni più fluide. Quando vengono ricevuti nuovi dati dal server, la pagina HTML corrente può essere aggiornata con JavaScript utilizzando l'API [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model). Nel tempo, questo approccio si è evoluto in ciò che ora viene chiamato [*Applicazione Singola Pagina* o *SPA*](https://en.wikipedia.org/wiki/Single-page_application).  Quando AJAX è stato introdotto per la prima volta, l'unica API disponibile per recuperare dati in modo asincrono era [`XMLHttpRequest`](https://developer.mozilla.org/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest). Tuttavia, i browser moderni ora implementano anche l'API [`Fetch`](https://developer.mozilla.org/docs/Web/API/Fetch_API), più comoda e potente, che utilizza le promesse ed è più adatta per manipolare dati JSON. > Sebbene tutti i browser moderni supportino l'API `Fetch`, se desideri che la tua applicazione web funzioni su browser legacy o vecchi, è sempre una buona idea controllare prima la [tabella di compatibilità su caniuse.com](https://caniuse.com/fetch). ### Compito Nella [lezione precedente](../2-forms/README.md) abbiamo implementato il modulo di registrazione per creare un account. Ora aggiungeremo il codice per effettuare il login utilizzando un account esistente e recuperare i suoi dati. Apri il file `app.js` e aggiungi una nuova funzione `login`: ```js async function login() { const loginForm = document.getElementById('loginForm') const user = loginForm.user.value; } ``` Qui iniziamo recuperando l'elemento del modulo con `getElementById()`, e poi otteniamo il nome utente dall'input con `loginForm.user.value`. Ogni controllo del modulo può essere accessibile tramite il suo nome (impostato nell'HTML utilizzando l'attributo `name`) come proprietà del modulo. In modo simile a quanto fatto per la registrazione, creeremo un'altra funzione per eseguire una richiesta al server, ma questa volta per recuperare i dati dell'account: ```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' }; } } ``` Utilizziamo l'API `fetch` per richiedere i dati in modo asincrono dal server, ma questa volta non abbiamo bisogno di parametri extra oltre all'URL da chiamare, poiché stiamo solo interrogando i dati. Per impostazione predefinita, `fetch` crea una richiesta HTTP [`GET`](https://developer.mozilla.org/docs/Web/HTTP/Methods/GET), che è ciò che ci serve qui. ✅ `encodeURIComponent()` è una funzione che esegue l'escape dei caratteri speciali per l'URL. Quali problemi potremmo avere se non chiamiamo questa funzione e utilizziamo direttamente il valore `user` nell'URL? Ora aggiorniamo la nostra funzione `login` per utilizzare `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'); } ``` Poiché `getAccount` è una funzione asincrona, dobbiamo abbinarla alla parola chiave `await` per attendere il risultato del server. Come per qualsiasi richiesta al server, dobbiamo anche gestire i casi di errore. Per ora aggiungeremo solo un messaggio di log per mostrare l'errore e ci torneremo più avanti. Dobbiamo poi salvare i dati da qualche parte per poterli utilizzare successivamente per mostrare le informazioni della dashboard. Poiché la variabile `account` non esiste ancora, creeremo una variabile globale all'inizio del nostro file: ```js let account = null; ``` Dopo che i dati dell'utente sono stati salvati in una variabile, possiamo navigare dalla pagina *login* alla *dashboard* utilizzando la funzione `navigate()` che abbiamo già. Infine, dobbiamo chiamare la nostra funzione `login` quando il modulo di login viene inviato, modificando l'HTML: ```html