# Costruire un'App Bancaria Parte 3: Metodi per Recuperare e Utilizzare 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 Devi aver costruito la parte [Modulo di Login e Registrazione](../2-forms/README.md) dell'app web per questa lezione. Inoltre, devi 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 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 devono essere caricati 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 (Asynchronous JavaScript and XML)](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, con aggiornamenti più rapidi e interazioni più fluide per l'utente. 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 è chiamato [*Applicazione a Pagina Singola* 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). Ma i browser moderni ora implementano anche la più comoda e potente [`Fetch` API](https://developer.mozilla.org/docs/Web/API/Fetch_API), che utilizza le promesse ed è più adatta per manipolare dati JSON. > Sebbene tutti i browser moderni supportino la `Fetch API`, se vuoi 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'); } ``` Per prima cosa, 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ù tardi. Poi dobbiamo salvare i dati da qualche parte per poterli utilizzare successivamente per mostrare le informazioni del dashboard. Poiché la variabile `account` non esiste ancora, creeremo una variabile globale per essa 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 di *login* al *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