modulo 11 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Stati vuoti, caricamento e messaggi semplici

Come gestire nella UI del Registro tre stati speciali — lista vuota, caricamento in corso, messaggio di successo o errore — con HTML e JavaScript concreti per ognuno dei tre stati.

25 min Architettura del software

Stati vuoti, caricamento e messaggi semplici

Questa lezione appartiene al Modulo 11 — Presentation: l’interfaccia come bordo del sistema.

Quando la lista degli strumenti è vuota, l’utente non deve vedere uno spazio bianco. Quando un’operazione è in corso, l’utente non deve chiedersi se il pulsante ha funzionato. Quando un prestito viene registrato con successo — o fallisce — l’utente deve saperlo in modo chiaro. Questi tre stati speciali sono parte dell’interfaccia, non un’aggiunta opzionale.

Obiettivo della lezione

In questa lezione impari a gestire nella UI del Registro i tre stati speciali: lista vuota, caricamento in corso e messaggio dopo un’operazione. Impari a scriverli in HTML e JavaScript senza mettere logica di dominio nell’interfaccia.

Alla fine devi avere un risultato verificabile: tre stati visibili nel browser, ognuno gestito da un frammento di codice separato e testabile manualmente.

I tre stati speciali

Stato 1 — Lista vuota La lista degli strumenti non ha elementi. Può succedere al primo avvio (nessuno strumento registrato ancora) o dopo una ricerca senza risultati.

Stato 2 — Caricamento in corso Un’operazione è stata avviata ma non è ancora terminata. Nel Registro questo accade con operazioni asincrone: lettura iniziale, salvataggio con conferma ritardata, operazioni simulate.

Stato 3 — Messaggio dopo un’operazione Un prestito è stato registrato, uno strumento è stato aggiunto, un guasto è stato segnalato. Oppure qualcosa è andato storto. L’utente deve vedere un feedback immediato e leggibile.

Procedura guidata

  1. Apri presentation/listaStrumenti.js e individua la funzione che renderizza la lista.
  2. Aggiungi il controllo per la lista vuota: se l’array è vuoto, mostra un messaggio invece della lista.
  3. Apri presentation/formPrestito.js e aggiungi la gestione del caricamento: disabilita il pulsante e mostra un indicatore visivo mentre l’operazione è in corso.
  4. Aggiungi la gestione del messaggio: mostra conferma dopo successo, messaggio di errore in caso di eccezione.
  5. Testa manualmente tutti e tre gli stati nel browser.
  6. Verifica che nessuno dei tre stati contenga logica di dominio (nessun stato === 'disponibile', nessuna chiamata ad archivioStrumenti).
  7. Aggiungi ogni stato alla checklist di test manuale.

Attività in classe

Completa il codice per ogni stato. Prima scrivi il comportamento atteso, poi il codice:

## I tre stati nella mia UI

Stato 1 — Lista vuota
  Quando succede: _______________
  Messaggio mostrato: _______________
  Elemento HTML usato: _______________

Stato 2 — Caricamento in corso
  Quando succede: _______________
  Elemento disabilitato: _______________
  Testo/icona mostrata: _______________
  Quando viene rimosso: _______________

Stato 3 — Messaggio operazione
  Messaggio di successo: _______________
  Messaggio di errore: _______________
  Dove viene mostrato: _______________
  Dopo quanti secondi scompare: _______________

Se lavori in gruppo, una persona scrive il codice e un’altra testa ogni stato manualmente nel browser.

Spiegazione guidata per studiare

La UI del Registro ha tre responsabilità: mostrare i dati, raccogliere l’input dell’utente e dare feedback sulle operazioni. I tre stati speciali di questa lezione riguardano tutti il feedback.

Lo stato vuoto non è un errore. È una situazione normale che l’interfaccia deve gestire con grazia. Un messaggio come “Nessuno strumento registrato. Aggiungi il primo strumento.” è più utile di uno spazio bianco.

Il caricamento in corso protegge l’utente dal fare doppio click o da credere che il sistema sia bloccato. Disabilitare il pulsante durante l’operazione è il minimo. Mostrare un testo come “Registrazione in corso…” è meglio.

Il messaggio di risultato chiude il ciclo di feedback. L’utente ha fatto un’azione: merita sapere se è andata a buon fine. Il messaggio deve essere specifico (“Prestito registrato per Mario Rossi”) non generico (“Operazione completata”).

La cosa importante è che nessuno di questi tre stati conosce le regole del dominio. Lo stato vuoto non sa perché la lista è vuota. Il messaggio di errore mostra il testo dell’eccezione, ma non decide se l’eccezione è giusta. Quella decisione sta nel caso d’uso e nel dominio.

Passo per passo nel progetto

  1. Apri presentation/listaStrumenti.js e trova dove viene iterata la lista per il render.
  2. Prima del ciclo di render, aggiungi: se la lista è vuota, mostra <p class="stato-vuoto">Nessuno strumento registrato.</p> e restituisci.
  3. Apri presentation/formPrestito.js e trova il gestore del click sul pulsante “Presta”.
  4. All’inizio del gestore, aggiungi: pulsante.disabled = true; pulsante.textContent = 'Registrazione in corso...';
  5. Nel blocco catch, aggiungi: pulsante.disabled = false; pulsante.textContent = 'Presta'; mostraErrore(err.message);
  6. Nel blocco then o dopo await, aggiungi: pulsante.disabled = false; pulsante.textContent = 'Presta'; mostraSuccesso('Prestito registrato.');
  7. Crea la funzione mostraMessaggio(testo, tipo) in un file separato presentation/messaggi.js.

Esempio da leggere lentamente

Questi tre frammenti mostrano ogni stato nel codice reale:

// presentation/listaStrumenti.js

function renderLista(strumenti) {
  const contenitore = document.getElementById('lista-strumenti');
  contenitore.innerHTML = '';

  // Stato 1: lista vuota
  if (strumenti.length === 0) {
    contenitore.innerHTML =
      '<p class="stato-vuoto">Nessuno strumento registrato. ' +
      'Usa il form sopra per aggiungere il primo.</p>';
    return;
  }

  // Caso normale: render degli strumenti
  strumenti.forEach(s => {
    const riga = document.createElement('div');
    riga.className = 'strumento-riga';
    riga.innerHTML = `<strong>${s.nome}</strong> — ${s.categoria} — ${s.stato}`;
    contenitore.appendChild(riga);
  });
}

// presentation/formPrestito.js

async function onClickPresta(evento) {
  evento.preventDefault();
  const pulsante = evento.target;
  const idStrumento = document.getElementById('id-strumento').value;
  const nomeStudente = document.getElementById('nome-studente').value;

  // Stato 2: caricamento in corso
  pulsante.disabled = true;
  pulsante.textContent = 'Registrazione in corso...';

  try {
    const prestito = await registraPrestito(idStrumento, nomeStudente);
    // Stato 3a: messaggio di successo
    mostraSuccesso(`Prestito registrato per ${prestito.nomeStudente}.`);
  } catch (errore) {
    // Stato 3b: messaggio di errore
    mostraErrore(errore.message);
  } finally {
    pulsante.disabled = false;
    pulsante.textContent = 'Presta';
  }
}

// presentation/messaggi.js

function mostraSuccesso(testo) {
  _mostraMessaggio(testo, 'successo');
}

function mostraErrore(testo) {
  _mostraMessaggio(testo, 'errore');
}

function _mostraMessaggio(testo, tipo) {
  const zona = document.getElementById('zona-messaggi');
  zona.textContent = testo;
  zona.className = `messaggio messaggio-${tipo}`;
  // Il messaggio scompare dopo 4 secondi
  setTimeout(() => { zona.textContent = ''; zona.className = ''; }, 4000);
}

Nota: messaggi.js non sa nulla di prestiti o strumenti. Sa solo come mostrare un testo in una zona della pagina. Questa ignoranza è corretta.

Prova di comprensione

Prima di chiudere la lezione, rispondi per iscritto a queste domande:

  • Cosa vede l’utente se nessuno strumento è ancora stato registrato nel Registro?
  • Perché disabilitare il pulsante durante il caricamento invece di lasciarlo attivo?
  • Dove viene costruito il testo del messaggio di errore — nella UI o nel caso d’uso?
  • Se mostraSuccesso e mostraErrore vengono usate in cinque pagine diverse, dove conviene tenerle?

Una risposta accettabile usa i nomi reali degli elementi HTML e delle funzioni del progetto.

Errori da evitare

  • lasciare la lista vuota senza nessun messaggio — l’utente non capisce se il sistema funziona;
  • non disabilitare il pulsante durante il caricamento — rischio di doppio invio;
  • mostrare solo "Errore" come messaggio senza il testo specifico dell’eccezione;
  • costruire il testo del messaggio dentro il caso d’uso — il caso d’uso non sa come la UI mostra i messaggi;
  • dimenticare il blocco finally: se non ripristini il pulsante dopo un errore, l’utente non può riprovare.

Prodotto da consegnare

Crea o aggiorna i seguenti file:

  • presentation/listaStrumenti.js con gestione dello stato vuoto;
  • presentation/formPrestito.js con gestione del caricamento e del risultato;
  • presentation/messaggi.js con mostraSuccesso e mostraErrore.

Testa manualmente i tre stati nel browser: lista vuota al primo avvio, pulsante disabilitato durante il prestito, messaggio di conferma e messaggio di errore.

Checklist di chiusura

Prima di chiudere la lezione, controlla:

  • lo stato vuoto mostra un messaggio leggibile invece di uno spazio bianco;
  • il pulsante si disabilita durante il caricamento e si riabilita al termine;
  • il messaggio di successo mostra il nome dello studente o il nome dello strumento;
  • il messaggio di errore mostra il testo dell’eccezione lanciata dal caso d’uso;
  • messaggi.js non importa nulla da domain/ né da application/.

Risultato atteso

Alla fine lo studente deve saper dire:

Nel Registro ho gestito tre stati speciali nella UI.
Lista vuota: mostro "Nessuno strumento registrato" invece di spazio bianco.
Caricamento: disabilito il pulsante e scrivo "Registrazione in corso...".
Messaggio: mostro conferma con il nome dello studente o errore con il testo dell'eccezione.
I messaggi stanno in presentation/messaggi.js, separati da dominio e application.

Se questa spiegazione non è possibile, la lezione non è ancora davvero conclusa.