Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Astro e htmx: selezione, modifica, rimozione dati e gestione errori

Astro e htmx: impariamo a recuperare e visualizzare i dati e aggiornare ed eliminare i record passando poi alla gestione degli errori
Astro e htmx: impariamo a recuperare e visualizzare i dati e aggiornare ed eliminare i record passando poi alla gestione degli errori
Link copiato negli appunti

Nella precedente lezione, abbiamo visto come inserire record nel database. Ora vedremo come recuperare e visualizzare i dati e come aggiornare ed eliminare i record.

Astro e htmx: il recupero dei dati

L'endpoint /list-items risponde a una richiesta GET attivata dalla ul#todo-list presente nel file /src/pages/index.astro. Ogni volta che viene caricata la pagina, la richiesta viene elaborata e l'endpoint restituisce il codice che genera l'elenco dei task. I dati di ogni task vengono visualizzati in una Card.

Creiamo un nuovo file list-items.astro nella cartella /src/pages e aggiungiamo al suo interno il seguente codice:

---
import { db, Todos, Categories, eq } from 'astro:db';
import Card from '../components/Card.astro';
const todos = await db.select().from(Todos).innerJoin(Categories, eq(Todos.catId, Categories.id));
---
{
	todos.map(({ Todos, Categories }) => (
		<Card
			id={Todos.id}
			title={Categories.category}
			body={Todos.task}
			done={Todos.done}
		/>
	))
}

Qui abbiamo selezionato tutti i record della tabella Todos e utilizzato una INNER JOIN per recuperare la categoria corrispondente dalla tabella Categories. Abbiamo quindi mappato l'oggetto todos per generare una Card per ogni task.

I task della todo list

I task della todo list

La modifica di un campo

Ora abbiamo bisogno di un endpoint che ci permetta di contrassegnare un task come completo o riportarlo allo stato precedente. In pratica, bisognerà modificare il valore del campo done di un record della tabella Todos.

Nella lezione precedente abbiamo inserito nel componente Card un pulsante Complete, che attiva una richiesta PATCH verso l'endpoint /update-item. L'endpoint /update-item eseguirà una query UPDATE e restituirà il markup di una nuova Card.

Creiamo il file /src/pages/update-item.astro e scriviamo il seguente codice:

---
import { db, Todos, Categories, eq, not } from 'astro:db';
import Card from '../components/Card.astro';
let taskId = 0;
let title = '';
let body = '';
let done = false;
if (Astro.request.method === 'PATCH') {
	const formData = await Astro.request.formData();
	const itemId = Number( formData.get('itemId') );
	if (typeof itemId === 'number') {
		const updatedRecord = await db.update(Todos)
			.set({ done: not(Todos.done) })
			.where(eq(Todos.id, itemId))
			.returning();
			taskId = updatedRecord[0].id;
			body = updatedRecord[0].task;
			done = updatedRecord[0].done;
			const result = await db.select().from(Categories).where(eq(Categories.id, updatedRecord[0].catId));
			title = result[0].category;
	}
}
---
<Card
	id={taskId}
	title={title}
	body={body}
	done={done}
/>

Se il metodo della richiesta è PATCH e il tipo di itemId è un numero, allora viene eseguita una query UPDATE per assegnare al campo done il valore not(Todos.done). La successiva query SELECT recupera il titolo della categoria corrispondente dalla tabella Categories. I valori così ottenuti vengono assegnati agli attributi dell'elemento Card.

Task completi e da completare

Task completi e da completare

L'eliminazione di un record

L'ultimo step è l'eliminazione di un record. Creiamo un nuovo file /src/pages/delete-item.astro e scriviamo il seguente codice:

---
import { db, Todos, eq } from 'astro:db';
if (Astro.request.method === 'DELETE') {
	const formData = await Astro.request.formData();
	const itemId = Number( formData.get('itemId') );
	if (typeof itemId === 'number') {
		await db.delete(Todos).where(eq(Todos.id, itemId));
	}
}
---

Se il metodo è DELETE, viene recuperato l'id dell'elemento cancellato nel record corrispondente. Non c'è markup da generare, in quanto si dovrà semplicemente eliminare l'elemento corrente.

Un endpoint per la gestione degli errori con Astro e htmx

Nella lezione precedente abbiamo visto che, in caso di errore nella compilazione dei campi del form, viene eseguito un redirect della richiesta verso l'endpoint /error.

Prima di creare l'endpoint, dobbiamo creare un elemento all'interno del DOM in cui visualizzare il messaggio di errore. Torniamo al file /src/layouts/Layout.astro e inseriamo una div subito dopo il tag di apertura dell'elemento body:

<body>
	<div id="error"></div>
	<slot />
</body>

Ora, sempre all'interno della cartella /src/pages, creiamo il file error.astro e inseriamo questo codice:

<script>console.log("Errore nella compilazione del form");</script>
<div
	id="error"
	hx-swap-oob="outerHTML"
>
	<div class="warning">Error! 😣</div>
</div>

Si noterà che la div che abbiamo inserito nel file /src/layouts/Layout.astro ha lo stesso id della div del file error.astro. L'attributo hx-swap-oob della seconda div specifica che alcuni contenuti di una risposta devono essere inseriti nel DOM in un punto diverso da quello di destinazione ("Out Of Band"). Ciò vuol dire che, in caso di errore di compilazione del form, la seconda div andrà a sostituire la prima nel file index.astro.

Possiamo rendere più evidente il messaggio di errore aggiungendo i seguenti stili nel file Layout.astro:

.warning {
	position: fixed;
	top: 0;
	left: 0;
	width: 100%;
	padding: 1em;
	font-size: 1.2em;
	font-weight: bold;
	text-align: center;
	background-color: rgb(142, 31, 0);
	color: white;
	transform: translateY(-100%);
	animation-name: errormessage;
	animation-duration: 4s;
}
@keyframes errormessage {
	0% {transform: translateY(-100%)}
	10% {transform: translateY(0%)}
	90% {transform: translateY(0%)}
	100% {transform: translateY(-100%)}
}

Un messaggio di errore

Un messaggio di errore

Conclusioni

Il nostro lavoro di sviluppo con Astro DB e htmx si conclude qui, ma c'è ancora qualcosa da fare prima di distribuire l'applicazione.

Per prima cosa, è necessario creare un progetto su Astro Studio seguendo le indicazioni della documentazione online. Una volta autenticati, bisognerà creare un nuovo progetto scegliendo tra le diverse opzioni disponibili.

Progetti in Astro Studio

Progetti in Astro Studio

Una volta collegato il progetto, potremo eseguire diverse operazioni, come collegare l'applicazione al progetto.

Creazione di un nuovo progetto in Astro Studio

Creazione di un nuovo progetto in Astro Studio

Ci fermiamo qui, lasciando ai lettori la configurazione del progetto e il deploy dell'app.

Il codice del progetto illustrato in questa guida è disponibile su GitHub

Il codice del progetto illustrato in questa guida è disponibile su GitHub

Il codice illustrato in questa guida è disponibile su GitHub. Happy coding!

Ti consigliamo anche