Lezioni del modulo (3/4)
Sfida: validatore di dati
Validare dati di input è una delle cose che farai più spesso: nessun form, nessuna API può fidarsi ciecamente di ciò che riceve. Costruiamo un piccolo validatore che combina regole componibili e ritorna tutti gli errori trovati, non solo il primo.
Una regola = una funzione
Una regola riceve l'oggetto e ritorna null (tutto ok) oppure una stringa col messaggio
d'errore.
const nomeRichiesto = (utente) =>
utente.nome && utente.nome.length > 0 ? null : 'nome obbligatorio';
const etaMaggiore = (utente) => (utente.eta >= 18 ? null : 'devi essere maggiorenne');Comporre più regole
Il validatore esegue tutte le regole e raccoglie gli errori:
function valida(utente, regole) {
const errori = [];
for (const regola of regole) {
const msg = regola(utente);
if (msg) errori.push(msg);
}
return errori;
}In stile funzionale:
const valida = (obj, regole) => regole.map((r) => r(obj)).filter((m) => m !== null);Decidere se è valido
const errori = valida(utente, [nomeRichiesto, etaMaggiore]);
const ok = errori.length === 0;Pattern utile: factory di regole
Quando hai molti campi da validare con la stessa logica, scrivi una factory:
const richiesto = (campo) => (obj) =>
obj[campo] != null && obj[campo] !== '' ? null : `${campo} obbligatorio`;
const minimo = (campo, n) => (obj) => (obj[campo] >= n ? null : `${campo} deve essere >= ${n}`);
const regole = [richiesto('nome'), richiesto('email'), minimo('eta', 18)];Ogni factory ritorna una funzione regola già configurata. È esattamente come usare un generatore di parser o un validator come Zod, solo in piccolo.
Prova tu
Definisci `validate(obj, rules)`: applica ogni regola (funzione obj -> stringa|null) e ritorna un array contenente solo i messaggi non-null, nello stesso ordine delle regole.
Mostra suggerimento
rules.map((r) => r(obj)).filter((m) => m !== null)
Soluzione disponibile dopo 3 tentativi
Esercizio di ripasso
Definisci la factory `required(field)`: ritorna una regola che dato un oggetto ritorna null se obj[field] è non-vuoto (non null, non undefined, non stringa vuota), altrimenti la stringa '<field> obbligatorio'.
Mostra suggerimento
Ritorna una closure che legge obj[field].
Soluzione disponibile dopo 3 tentativi