From dd1fb79c7ca6378bc3297ecf56ddd49fbd22a5f2 Mon Sep 17 00:00:00 2001 From: Berack96 Date: Sun, 1 Mar 2026 20:49:28 +0100 Subject: [PATCH] ripasso: fixes --- javascript/ripasso_completo/README.md | 28 +- .../esercizio_3_api/index.html | 473 ++++++++++++++ .../esercizio_3_api/script.js | 577 ++++++++++++++++++ server-api/database/db.json | 162 +++++ 4 files changed, 1239 insertions(+), 1 deletion(-) create mode 100644 javascript/ripasso_completo/esercizio_3_api/index.html create mode 100644 javascript/ripasso_completo/esercizio_3_api/script.js diff --git a/javascript/ripasso_completo/README.md b/javascript/ripasso_completo/README.md index 449737a..cf4fa97 100644 --- a/javascript/ripasso_completo/README.md +++ b/javascript/ripasso_completo/README.md @@ -2,7 +2,7 @@ ## Obiettivo -Questi due esercizi coprono **TUTTO** il programma JavaScript, dal primo `console.log` fino a `localStorage`. +Questi esercizi coprono **TUTTO** il programma JavaScript, dal primo `console.log` fino alle `API`. Sono pensati per essere fatti **in autonomia**, senza bisogno di aiuto, a patto di seguire le istruzioni passo passo e di non saltare nessun concetto. --- @@ -18,6 +18,7 @@ Sono pensati per essere fatti **in autonomia**, senza bisogno di aiuto, a patto 7. **Non saltare nessun step** β€” ogni step usa ciΓ² che hai fatto prima 8. Salva e ricarica la pagina per vedere i risultati 9. Quando hai finito il primo esercizio, ripeti i passaggi 3-8 per il secondo esercizio +10. Per il **terzo esercizio** (API), prima avvia il server: apri il terminale nella cartella `server-api` e lancia `npm start` --- @@ -74,6 +75,31 @@ Se ti blocchi, torna all'Esercizio 1 per rivedere il concetto. --- +### Esercizio 3 β€” "La Biblioteca Online" (API) + +Un esercizio dedicato alla **comunicazione con un server API** usando `fetch()`. +Copre le operazioni CRUD: + +| Step | Operazione | Metodo HTTP | Cosa fa | +| ---- | ---------- | ----------- | ---------------------------- | +| 1 | READ | GET | Caricare tutti i libri | +| 2 | READ | GET | Cercare un libro per ID | +| 3 | CREATE | POST | Aggiungere un nuovo libro | +| 4 | UPDATE | PATCH | Segnare un libro come letto | +| 5 | DELETE | DELETE | Eliminare un libro | +| 6 | BONUS | β€” | Caricamento auto, filtri, ricerca | + +**Prerequisito:** avviare il server API prima di iniziare (chiedere al docente). + +Per ogni step trovi: + +- πŸ“– **Spiegazione** del concetto (fetch, async/await, metodi HTTP) +- πŸ’‘ **Esempio** di sintassi +- ✏️ **TODO** β€” il codice che devi scrivere tu +- βœ… **Verifica** β€” come controllare che hai fatto giusto + +--- + ## Regola d'oro > **Se non ricordi come si fa qualcosa, rileggilo nell'Esercizio 1.**\ diff --git a/javascript/ripasso_completo/esercizio_3_api/index.html b/javascript/ripasso_completo/esercizio_3_api/index.html new file mode 100644 index 0000000..c8ebed8 --- /dev/null +++ b/javascript/ripasso_completo/esercizio_3_api/index.html @@ -0,0 +1,473 @@ + + + + + + Esercizio 3 β€” La Biblioteca Online (API) + + + + +
+

πŸ“š La Biblioteca Online

+

Ripasso API β€” fetch, async/await, CRUD

+ +
+ ⚠️ Prima di iniziare, assicurati che il server sia avviato e funzionante. +
+ + +
+ + +
+
+
Totale Libri
+
0
+
+
+
GiΓ  Letti
+
0
+
+
+
Da Leggere
+
0
+
+
+ + +
+
+

Caricamento in corso...

+
+ + +
+

πŸ“‹ Lista Libri

+
+ +
+
    +
    +
    πŸ“š
    +

    Clicca "Carica Tutti i Libri" per iniziare

    +
    +
+
+ + +
+

πŸ”Ž Cerca Libro per ID

+
+ + +
+
+
+ + +
+

βž• Aggiungi Nuovo Libro

+
+ + +
+
+ + +
+ +
+ + +
+

✏️ Segna come Letto / Non Letto

+
+ + + +
+
+ + +
+

πŸ—‘οΈ Elimina Libro

+
+ + +
+
+ +
+ + + + diff --git a/javascript/ripasso_completo/esercizio_3_api/script.js b/javascript/ripasso_completo/esercizio_3_api/script.js new file mode 100644 index 0000000..8104452 --- /dev/null +++ b/javascript/ripasso_completo/esercizio_3_api/script.js @@ -0,0 +1,577 @@ +// ╔══════════════════════════════════════════════════════════════════════════════╗ +// β•‘ πŸ“š LA BIBLIOTECA ONLINE β€” ESERCIZIO API (GUIDATO) β•‘ +// β•‘ β•‘ +// β•‘ Questo esercizio ti insegna a comunicare con un SERVER usando fetch(). β•‘ +// β•‘ Imparerai le operazioni CRUD: β•‘ +// β•‘ β•‘ +// β•‘ πŸ“₯ GET β€” leggere dati dal server β•‘ +// β•‘ πŸ“€ POST β€” inviare/creare nuovi dati β•‘ +// β•‘ ✏️ PATCH β€” modificare dati esistenti β•‘ +// β•‘ πŸ—‘οΈ DELETE β€” eliminare dati β•‘ +// β•‘ β•‘ +// β•‘ COME FUNZIONA QUESTO ESERCIZIO: β•‘ +// β•‘ Per ogni step trovi: β•‘ +// β•‘ 1. πŸ’‘ ESEMPIO β€” codice GIΓ€ FUNZIONANTE che gira davvero β•‘ +// β•‘ 2. ✏️ TODO β€” devi RIFARE la stessa cosa per un caso diverso β•‘ +// β•‘ β•‘ +// β•‘ PRIMA DI INIZIARE: β•‘ +// β•‘ 1. Apri un terminale nella cartella "server-api" β•‘ +// β•‘ 2. Lancia: npm start β•‘ +// β•‘ 3. Il server sarΓ  attivo su http://localhost:5000/api β•‘ +// β•‘ 4. I libri sono su http://localhost:5000/api/books β•‘ +// β•‘ β•‘ +// β•‘ STRUTTURA DI UN LIBRO NEL DATABASE: β•‘ +// β•‘ { β•‘ +// β•‘ "id": 1, β•‘ +// β•‘ "titolo": "Il nome della rosa", β•‘ +// β•‘ "autore": "Umberto Eco", β•‘ +// β•‘ "genere": "Giallo", β•‘ +// β•‘ "pagine": 512, β•‘ +// β•‘ "letto": true β•‘ +// β•‘ } β•‘ +// β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β• + + +// ============================================================================ +// SETUP β€” URL BASE E SELEZIONE ELEMENTI (giΓ  fatto, controlla URL) +// ============================================================================ + +const BASE_URL = "http://localhost:5000/api"; + +// Elementi della pagina +const btnCaricaTutti = document.querySelector("#btn-carica-tutti"); +const btnDettaglio = document.querySelector("#btn-dettaglio"); +const btnAggiungi = document.querySelector("#btn-aggiungi"); +const btnModifica = document.querySelector("#btn-modifica"); +const btnElimina = document.querySelector("#btn-elimina"); + +const listaLibri = document.querySelector("#lista-libri"); +const dettaglioLibro = document.querySelector("#dettaglio-libro"); +const loading = document.querySelector("#loading"); +const messaggio = document.querySelector("#messaggio"); + +const statTotale = document.querySelector("#stat-totale"); +const statLetti = document.querySelector("#stat-letti"); +const statDaLeggere = document.querySelector("#stat-da-leggere"); + + +// ============================================================================ +// FUNZIONI HELPER (giΓ  fatte, NON modificare) +// ============================================================================ + +/** + * Mostra lo spinner di caricamento + */ +function mostraLoading() { + loading.classList.add("visibile"); +} + +/** + * Nasconde lo spinner di caricamento + */ +function nascondiLoading() { + loading.classList.remove("visibile"); +} + +/** + * Mostra un messaggio di feedback (successo o errore) + * @param {string} testo - Il testo del messaggio + * @param {string} tipo - "successo" oppure "errore" + */ +function mostraMessaggio(testo, tipo) { + messaggio.textContent = testo; + messaggio.className = ""; + messaggio.classList.add("msg-" + tipo); + messaggio.style.display = "block"; + setTimeout(() => { + messaggio.style.display = "none"; + }, 3000); +} + +/** + * Aggiorna le statistiche nel DOM + * @param {Array} libri - L'array di libri ricevuto dal server + */ +function aggiornaStatistiche(libri) { + const totale = libri.length; + const letti = libri.filter((libro) => libro.letto === true).length; + const daLeggere = totale - letti; + statTotale.textContent = totale; + statLetti.textContent = letti; + statDaLeggere.textContent = daLeggere; +} + +/** + * Crea l'HTML di un singolo libro nella lista + * @param {Object} libro - L'oggetto libro dal server + * @returns {string} - L'HTML della riga + */ +function creaRigaLibro(libro) { + const badgeLetto = ` + + ${libro.letto ? "βœ… Letto" : "πŸ“– Da leggere"} + `; + + return ` +
  • +
    +
    ${libro.titolo}
    +
    + ✍️ ${libro.autore} | πŸ“„ ${libro.pagine} pagine | ${badgeLetto} +
    +
    +
    ID: ${libro.id}
    +
  • `; +} + + + + +// ============================================================================ +// STEP 1 β€” GET: LEGGERE DATI DAL SERVER +// ============================================================================ + +// β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +// β”‚ πŸ“– CONCETTI CHIAVE β”‚ +// β”‚ β”‚ +// β”‚ β€’ fetch(url) fa una richiesta al server (di default Γ¨ GET) β”‚ +// β”‚ β€’ fetch Γ¨ ASINCRONO β†’ usiamo async/await per aspettare la risposta β”‚ +// β”‚ β€’ risposta.ok β†’ true se il server ha risposto con successo β”‚ +// β”‚ β€’ risposta.json() β†’ converte la risposta in un oggetto/array JS β”‚ +// β”‚ β€’ try/catch β†’ gestisce gli errori (server spento, URL sbagliato, ecc.) β”‚ +// β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + +// ── πŸ’‘ ESEMPIO FUNZIONANTE ────────────────────────────── +// Questa funzione FUNZIONA GIΓ€. Carica il libro con ID 1 +// e stampa i suoi dati in console. +// Apri la Console (F12) per vedere il risultato. + +async function esempioCaricaUnLibro() { + try { + const risposta = await fetch(BASE_URL + "/books/1"); + + if (!risposta.ok) { + throw new Error("Errore dal server: " + risposta.status); + } + + const libro = await risposta.json(); + + console.log("--- ESEMPIO GET singolo ---"); + console.log("Titolo:", libro.titolo); // β†’ "Il nome della rosa" + console.log("Autore:", libro.autore); // β†’ "Umberto Eco" + console.log("Oggetto completo:", libro); + } catch (errore) { + console.error("Errore nell'esempio:", errore.message); + } +} + +// Eseguiamo l'esempio automaticamente all'apertura della pagina: +esempioCaricaUnLibro(); + +// ── ✏️ ORA TOCCA A TE ────────────────────────────────── +// Hai visto come caricare UN libro. +// Adesso devi caricare TUTTI i libri e mostrarli nella lista. +// +// L'URL per tutti i libri Γ¨: BASE_URL + "/books" +// (senza /1 alla fine β†’ restituisce un ARRAY invece di un oggetto) +// +// Devi: +// 1. Chiamare mostraLoading() +// 2. try/catch come nell'esempio sopra +// 3. Dentro il try: +// a. fetch GET a BASE_URL + "/books" +// b. Controllare risposta.ok +// c. Convertire in JSON β†’ sarΓ  un ARRAY di libri +// d. Svuotare la lista: listaLibri.innerHTML = "" +// e. Per ogni libro, aggiungere una riga: +// for (const libro of libri) { +// listaLibri.innerHTML += creaRigaLibro(libro); +// } +// f. Aggiornare le statistiche: aggiornaStatistiche(libri) +// g. mostraMessaggio("Libri caricati!", "successo") +// 4. Dentro il catch: +// mostraMessaggio(errore.message, "errore") +// 5. Alla fine (dopo il catch): nascondiLoading() + +async function caricaTuttiILibri() { + // πŸ‘‡ SCRIVI QUI IL TUO CODICE + +} + +// βœ… VERIFICA: Clicca "Carica Tutti i Libri" sulla pagina β†’ appaiono 20 libri nella lista +// Le statistiche mostrano: 20 totali, 10 letti, 10 da leggere + + + + +// ============================================================================ +// STEP 2 β€” GET CON ID: LEGGERE UN SINGOLO ELEMENTO +// ============================================================================ + +// ── πŸ’‘ ESEMPIO FUNZIONANTE ────────────────────────────── +// Questa funzione FUNZIONA GIΓ€. Carica il libro con ID 2 +// e lo mostra nel div #dettaglio-libro. + +async function esempioMostraDettaglio() { + try { + const risposta = await fetch(BASE_URL + "/books/2"); + + if (!risposta.ok) { + throw new Error("Libro non trovato (errore " + risposta.status + ")"); + } + + const libro = await risposta.json(); + + // Mostriamo il dettaglio nella pagina + dettaglioLibro.innerHTML = ` +

    ${libro.titolo}

    +

    ✍️ Autore: ${libro.autore}

    +

    πŸ“‚ Genere: ${libro.genere}

    +

    πŸ“„ Pagine: ${libro.pagine}

    +

    Stato: ${libro.letto ? "Letto βœ…" : "Da leggere πŸ“–"}

    + `; + + dettaglioLibro.classList.add("visibile"); + + console.log("--- ESEMPIO GET per ID ---"); + console.log("Caricato:", libro.titolo); + } catch (errore) { + console.error("Errore nell'esempio:", errore.message); + } +} + +// Eseguiamo l'esempio (mostra il libro 2 nel dettaglio): +esempioMostraDettaglio(); + +// ── ✏️ ORA TOCCA A TE ────────────────────────────────── +// Hai visto come caricare un libro con un ID fisso (2). +// Adesso devi fare la stessa cosa, ma leggendo l'ID dall'input. +// +// Per leggere l'input: +// const id = document.querySelector("#input-id").value; +// +// ⚠️ .value restituisce una STRINGA. Per validare: +// if (!id || isNaN(id)) { mostraMessaggio("Inserisci un ID valido!", "errore"); return; } +// +// Devi: +// 1. Leggere l'ID dall'input +// 2. Validare che sia un numero +// 3. mostraLoading() +// 4. try/catch come nell'esempio sopra, ma con l'ID dinamico: +// fetch(BASE_URL + "/books/" + id) +// 5. Nel catch: mostraMessaggio(errore.message, "errore") +// 6. Alla fine: nascondiLoading() + +async function cercaLibroPerId() { + // πŸ‘‡ SCRIVI QUI IL TUO CODICE + +} + +// βœ… VERIFICA: Inserisci "3" nella pagina HTML β†’ vedi "Il piccolo principe" +// Inserisci "99" β†’ vedi un messaggio di errore + + + + +// ============================================================================ +// STEP 3 β€” POST: CREARE UN NUOVO ELEMENTO +// ============================================================================ + +// ── πŸ’‘ ESEMPIO FUNZIONANTE ────────────────────────────── +// Questa funzione FUNZIONA GIΓ€. Aggiunge un libro fisso +// ("Moby Dick") al server e lo stampa in console. +// Il server gli assegna un ID automaticamente. + +async function esempioAggiungiLibro() { + try { + const risposta = await fetch(BASE_URL + "/books", { + method: "POST", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + titolo: "Moby Dick", + autore: "Herman Melville", + genere: "Narrativa", + pagine: 635, + letto: false + }) + }); + + if (!risposta.ok) { + throw new Error("Errore nella creazione: " + risposta.status); + } + + const libroCreato = await risposta.json(); + + console.log("--- ESEMPIO POST ---"); + console.log("Libro creato:", libroCreato); + console.log("ID assegnato dal server:", libroCreato.id); + } catch (errore) { + console.error("Errore nell'esempio POST:", errore.message); + } +} + +// Lo eseguiamo per vedere il risultato in console: +esempioAggiungiLibro(); + +// ── ✏️ ORA TOCCA A TE ────────────────────────────────── +// Hai visto come fare una POST con dati fissi. +// Adesso devi fare la stessa cosa, ma leggendo i dati dal FORM. +// +// Per leggere i campi: +// const titolo = document.querySelector("#input-titolo").value; +// const autore = document.querySelector("#input-autore").value; +// const genere = document.querySelector("#select-genere").value; +// const pagine = parseInt(document.querySelector("#input-pagine").value); +// +// Devi: +// 1. Leggere i valori dal form +// 2. Validare che titolo e autore non siano vuoti: +// if (!titolo || !autore) { mostraMessaggio("Compila titolo e autore!", "errore"); return; } +// 3. mostraLoading() +// 4. try/catch: +// a. Creare l'oggetto: { titolo, autore, genere: genere || "Narrativa", pagine: pagine || 0, letto: false } +// b. Fare la fetch POST (come nell'esempio sopra, ma con i dati del form) +// c. Controllare risposta.ok +// d. mostraMessaggio("Libro aggiunto!", "successo") +// e. Svuotare gli input (metti .value = "") +// f. Ricaricare la lista: caricaTuttiILibri() +// 5. Nel catch: mostraMessaggio(errore.message, "errore") +// 6. Alla fine: nascondiLoading() + +async function aggiungiLibro() { + // πŸ‘‡ SCRIVI QUI IL TUO CODICE + +} + +// βœ… VERIFICA: Compila il form, clicca "Aggiungi Libro" +// β†’ Il nuovo libro appare nella lista, gli input si svuotano + + + + +// ============================================================================ +// STEP 4 β€” PATCH: MODIFICARE UN ELEMENTO ESISTENTE (UPDATE PARZIALE) +// ============================================================================ + +// β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +// β”‚ πŸ“– CONCETTI CHIAVE β”‚ +// β”‚ β”‚ +// β”‚ Per MODIFICARE un dato esistente, usiamo PATCH (o PUT). β”‚ +// β”‚ β”‚ +// β”‚ DIFFERENZA: β”‚ +// β”‚ β€’ PUT β†’ sostituisce TUTTO l'oggetto (devi mandare tutti i campi) β”‚ +// β”‚ β€’ PATCH β†’ modifica SOLO i campi che vuoi (piΓΉ comodo!) β”‚ +// β”‚ β”‚ +// β”‚ Esempio: voglio cambiare solo "letto" da false a true. β”‚ +// β”‚ Con PATCH: mando solo { letto: true } β”‚ +// β”‚ Con PUT: dovrei mandare { id, titolo, autore, genere, pagine, letto } β”‚ +// β”‚ β”‚ +// β”‚ Per specificare QUALE elemento modificare β†’ l'ID va nell'URL. β”‚ +// β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + +// ── πŸ’‘ ESEMPIO FUNZIONANTE ────────────────────────────── +// Questa funzione FUNZIONA GIΓ€. Segna il libro con ID 4 ("1984") +// come "letto" e stampa il risultato in console. +// +// PATCH modifica SOLO i campi che mandi nel body. +// Non serve mandare tutto l'oggetto, solo ciΓ² che cambia. + +async function esempioModificaLibro() { + try { + const risposta = await fetch(BASE_URL + "/books/4", { + method: "PATCH", + headers: { + "Content-Type": "application/json" + }, + body: JSON.stringify({ + letto: true // modifica SOLO il campo "letto" + }) + }); + + if (!risposta.ok) { + throw new Error("Errore nella modifica: " + risposta.status); + } + + const libroModificato = await risposta.json(); + + console.log("--- ESEMPIO PATCH ---"); + console.log("Libro modificato:", libroModificato.titolo); + console.log("Ora letto:", libroModificato.letto); // β†’ true + } catch (errore) { + console.error("Errore nell'esempio PATCH:", errore.message); + } +} + +// Lo eseguiamo: +esempioModificaLibro(); + +// ── ✏️ ORA TOCCA A TE ────────────────────────────────── +// Hai visto come fare una PATCH con ID e valore fissi. +// Adesso devi fare la stessa cosa, ma leggendo ID e stato dal form. +// +// Per leggere i campi: +// const id = document.querySelector("#input-modifica-id").value; +// const selectLetto = document.querySelector("#select-letto").value; +// +// ⚠️ ATTENZIONE: selectLetto sarΓ  la STRINGA "true" o "false" +// Per convertirla in booleano: +// const letto = selectLetto === "true"; +// +// Devi: +// 1. Leggere ID e stato dal form +// 2. Validare che l'ID sia un numero +// 3. mostraLoading() +// 4. try/catch: +// a. Fare la fetch PATCH a BASE_URL + "/books/" + id +// con body: { letto: letto } +// b. Controllare risposta.ok +// c. mostraMessaggio("Libro aggiornato!", "successo") +// d. Ricaricare la lista: caricaTuttiILibri() +// 5. Nel catch: mostraMessaggio(errore.message, "errore") +// 6. Alla fine: nascondiLoading() + +async function modificaLibro() { + // πŸ‘‡ SCRIVI QUI IL TUO CODICE + +} + +// βœ… VERIFICA: Inserisci ID 5, seleziona "Letto", clicca "Aggiorna" +// β†’ "Il Signore degli Anelli" passa a "Letto βœ…" + + + + +// ============================================================================ +// STEP 5 β€” DELETE: ELIMINARE UN ELEMENTO +// ============================================================================ + +// ── πŸ’‘ ESEMPIO FUNZIONANTE ────────────────────────────── +// Questa funzione FUNZIONA GIΓ€. Elimina il libro con ID 20 +// ("Il diario di Anna Frank") e stampa il risultato. +// +// DELETE Γ¨ il metodo piΓΉ semplice: solo method e URL, niente body. + +async function esempioEliminaLibro() { + try { + const risposta = await fetch(BASE_URL + "/books/20", { + method: "DELETE" + }); + + if (!risposta.ok) { + throw new Error("Errore nell'eliminazione: " + risposta.status); + } + + console.log("--- ESEMPIO DELETE ---"); + console.log("Libro con ID 20 eliminato con successo!"); + } catch (errore) { + console.error("Errore nell'esempio DELETE:", errore.message); + } +} + +// Lo eseguiamo: +esempioEliminaLibro(); + +// ── ✏️ ORA TOCCA A TE ────────────────────────────────── +// Hai visto come fare una DELETE con un ID fisso. +// Adesso devi fare la stessa cosa, ma leggendo l'ID dall'input +// e chiedendo conferma all'utente. +// +// Per chiedere conferma: +// if (!confirm("Sei sicuro di voler eliminare il libro " + id + "?")) { +// return; // l'utente ha cliccato "Annulla" +// } +// +// Devi: +// 1. Leggere l'ID da #input-elimina-id +// 2. Validare che sia un numero +// 3. Chiedere conferma con confirm() +// 4. mostraLoading() +// 5. try/catch: +// a. Fare la fetch DELETE a BASE_URL + "/books/" + id +// b. Controllare risposta.ok +// c. mostraMessaggio("Libro eliminato!", "successo") +// d. Svuotare l'input +// e. Ricaricare la lista: caricaTuttiILibri() +// 6. Nel catch: mostraMessaggio(errore.message, "errore") +// 7. Alla fine: nascondiLoading() + +async function eliminaLibro() { + // πŸ‘‡ SCRIVI QUI IL TUO CODICE + +} + +// βœ… VERIFICA: Inserisci un ID, clicca "Elimina" +// β†’ Compare un confirm, se confermi il libro sparisce + + + + +// ============================================================================ +// COLLEGAMENTO EVENTI (giΓ  fatto, NON modificare) +// ============================================================================ + +btnCaricaTutti.addEventListener("click", caricaTuttiILibri); +btnDettaglio.addEventListener("click", cercaLibroPerId); +btnAggiungi.addEventListener("click", aggiungiLibro); +btnModifica.addEventListener("click", modificaLibro); +btnElimina.addEventListener("click", eliminaLibro); + + + + +// ============================================================================ +// STEP 6 β€” BONUS (facoltativo) +// ============================================================================ + +// β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +// β”‚ Se hai completato tutti gli step, prova queste sfide extra! β”‚ +// β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ + +// ───────────────────────────────────────────────────────── +// ✏️ BONUS 1 β€” Carica i libri automaticamente all'apertura +// ───────────────────────────────────────────────────────── +// Chiama caricaTuttiILibri() quando la pagina si carica. +// Suggerimento: basta una riga di codice qui sotto! + +// πŸ‘‡ SCRIVI QUI IL TUO CODICE (Bonus 1) + + + + + +// ───────────────────────────────────────────────────────── +// ✏️ BONUS 2 β€” Filtra i libri per stato (letti / da leggere) +// ───────────────────────────────────────────────────────── +// Il server supporta i filtri via query string: +// /api/books?letto=true β†’ solo i libri letti +// /api/books?letto=false β†’ solo quelli da leggere +// +// Crea una funzione "caricaPerStato" che riceve un parametro booleano +// e fa una fetch con il filtro. Poi collegala a due nuovi bottoni +// (puoi aggiungerli nell'HTML o crearli via JS). + +// πŸ‘‡ SCRIVI QUI IL TUO CODICE (Bonus 2) + + + + + +// ───────────────────────────────────────────────────────── +// ✏️ BONUS 3 β€” Ricerca libri per titolo +// ───────────────────────────────────────────────────────── +// Il server supporta la ricerca: +// /api/books?q=harry β†’ cerca "harry" in tutti i campi +// +// Aggiungi un evento "input" sull'input di ricerca che filtra +// i libri in tempo reale dal server. + +// πŸ‘‡ SCRIVI QUI IL TUO CODICE (Bonus 3) + + + + + +// βœ… Se hai completato tutto, complimenti! +// Hai imparato a fare GET, POST, PATCH e DELETE con fetch + async/await! πŸŽ‰ diff --git a/server-api/database/db.json b/server-api/database/db.json index f63aa1a..adfffd1 100644 --- a/server-api/database/db.json +++ b/server-api/database/db.json @@ -789,5 +789,167 @@ "immagine": "https://media.startech.com/cms/products/gallery_large/laptop-stand-silver.main.jpg", "disponibilita": true } + ], + "books": [ + { + "id": 1, + "titolo": "Il nome della rosa", + "autore": "Umberto Eco", + "genere": "Giallo", + "pagine": 512, + "letto": true + }, + { + "id": 2, + "titolo": "Harry Potter e la pietra filosofale", + "autore": "J.K. Rowling", + "genere": "Fantasy", + "pagine": 293, + "letto": true + }, + { + "id": 3, + "titolo": "Il piccolo principe", + "autore": "Antoine de Saint-ExupΓ©ry", + "genere": "Narrativa", + "pagine": 96, + "letto": true + }, + { + "id": 4, + "titolo": "1984", + "autore": "George Orwell", + "genere": "Fantascienza", + "pagine": 328, + "letto": false + }, + { + "id": 5, + "titolo": "Il Signore degli Anelli", + "autore": "J.R.R. Tolkien", + "genere": "Fantasy", + "pagine": 1216, + "letto": false + }, + { + "id": 6, + "titolo": "Orgoglio e pregiudizio", + "autore": "Jane Austen", + "genere": "Romanzo", + "pagine": 432, + "letto": true + }, + { + "id": 7, + "titolo": "Fahrenheit 451", + "autore": "Ray Bradbury", + "genere": "Fantascienza", + "pagine": 158, + "letto": false + }, + { + "id": 8, + "titolo": "Diario di una schiappa", + "autore": "Jeff Kinney", + "genere": "Umorismo", + "pagine": 217, + "letto": true + }, + { + "id": 9, + "titolo": "IT", + "autore": "Stephen King", + "genere": "Horror", + "pagine": 1138, + "letto": false + }, + { + "id": 10, + "titolo": "Il codice da Vinci", + "autore": "Dan Brown", + "genere": "Giallo", + "pagine": 597, + "letto": true + }, + { + "id": 11, + "titolo": "Percy Jackson e gli dei dell'Olimpo", + "autore": "Rick Riordan", + "genere": "Fantasy", + "pagine": 375, + "letto": true + }, + { + "id": 12, + "titolo": "Assassinio sull'Orient Express", + "autore": "Agatha Christie", + "genere": "Giallo", + "pagine": 256, + "letto": false + }, + { + "id": 13, + "titolo": "Hunger Games", + "autore": "Suzanne Collins", + "genere": "Fantascienza", + "pagine": 374, + "letto": true + }, + { + "id": 14, + "titolo": "Il giovane Holden", + "autore": "J.D. Salinger", + "genere": "Narrativa", + "pagine": 214, + "letto": false + }, + { + "id": 15, + "titolo": "Shining", + "autore": "Stephen King", + "genere": "Horror", + "pagine": 447, + "letto": true + }, + { + "id": 16, + "titolo": "Il vecchio e il mare", + "autore": "Ernest Hemingway", + "genere": "Narrativa", + "pagine": 127, + "letto": false + }, + { + "id": 17, + "titolo": "Maze Runner - Il labirinto", + "autore": "James Dashner", + "genere": "Fantascienza", + "pagine": 384, + "letto": false + }, + { + "id": 18, + "titolo": "Frankenstein", + "autore": "Mary Shelley", + "genere": "Horror", + "pagine": 280, + "letto": true + }, + { + "id": 19, + "titolo": "Le cronache di Narnia", + "autore": "C.S. Lewis", + "genere": "Fantasy", + "pagine": 767, + "letto": false + }, + { + "id": 20, + "titolo": "Il diario di Anna Frank", + "autore": "Anna Frank", + "genere": "Narrativa", + "pagine": 283, + "letto": true + } ] } \ No newline at end of file