Como vimos en capítulos anteriores, en Ajax hay varios pasos que seguir:
- Crear la instancia del objeto.
- El listener.
- Abrir la petición.
- Enviar la petición.
Para cada una de las 4 operaciones del CRUD tendríamos que hacer lo mismo en Ajax, entonces lo que conviene es justamente lo que hacen librerías como Axios, crear una función que encapsule todo y pida los elementos necesarios.
Es importante levantar el servidor, al estar utilizando la API falsa de JSON Placeholder, para ello utilizamos la siguiente sintaxis.
json-server -w -p 5555 assets/db.json
De esta manera levantamos el archivo db.json que se encuentra en la carpeta assets de nuestro servidor.
Vamos a crear una función ajax() a la que le vamos a pasar un objeto, y utilizaremos la destructuración de dicho objeto.
const ajax = (options) => {
let(url, method, success, error, data} = options;
}
Así como un documento tiene cabecera y cuerpo, las peticiones HTTP tienen también cabecera, en este caso hay que incluir en nuestro script que el tipo de contenido es de tipo application/json, para lo que incluiremos la siguiente sintaxis. Vamos a aprender como agregar cabeceras a las peticiones HTTP. Para ello se utiliza un método denominado setRequestHeader(), de la siguiente forma
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
Si le quitamos esta cabecera, el JSON Server que está esperando no va a funcionar.
Veamos la sintaxis completa del ejm.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CRUD API REST Ajax</title>
</head>
<body>
<h1>CRUD API REST Ajax</h1>
<section id="crud">
<article>
<h2 class="crud-title">Agregar nombre</h2>
<form class="crud-form">
<input type="hidden" name="id" />
<input type="text" name="nombre" placeholder="nombre" required />
<br />
<input
type="email"
name="constelacion"
placeholder="constelación"
required
/>
<br />
<input type="submit" value="Enviar" />
</form>
</article>
<article>
<h2>Ver nombres</h2>
<table class="crud-table">
<thead>
<tr>
<th>Nombre</th>
<th>Constelación</th>
<th>Acciones</th>
</tr>
</thead>
<tbody></tbody>
</table>
</article>
</section>
<template id="crud-template">
<tr>
<td class="name"></td>
<td class="constellation"></td>
<td>
<button class="edit">Editar</button>
<button class="delete">Eliminar</button>
</td>
</tr>
</template>
<script>
const d = document,
$table = d.querySelector(".crud-table"),
$form = d.querySelector(".crud-form"),
$title = d.querySelector(".crud-title"),
$template = d.getElementById("crud-template").content,
$fragment = d.createDocumentFragment();
const ajax = (options) => {
// Usamos destructuración
let { url, method, success, error, data } = options;
const xhr = new XMLHttpRequest();
xhr.addEventListener("readystatechange", (e) => {
if (xhr.readyState !== 4) return;
if (xhr.status >= 200 && xhr.status < 300) {
let json = JSON.parse(xhr.responseText);
success(json);
} else {
let message = xhr.statusText || "Ocurrió un error";
error(`Error ${xhr.status}: ${message}`);
}
});
xhr.open(method || "GET", url);
xhr.setRequestHeader("Content-Type", "application/json; charset=utf-8");
xhr.send(JSON.stringify(data));
};
const getAll = () => {
ajax({
url: "http://localhost:5555/santos",
success: (res) => {
console.log(res);
res.forEach((el) => {
$template.querySelector(".name").textContent = el.nombre;
$template.querySelector(".constellation").textContent =
el.constelacion;
$template.querySelector(".edit").dataset.id = el.id;
$template.querySelector(".edit").dataset.name = el.nombre;
$template.querySelector(".edit").dataset.constellation =
el.constelacion;
$template.querySelector(".delete").dataset.id = el.id;
let $clone = d.importNode($template, true);
$fragment.appendChild($clone);
});
$table.querySelector("tbody").appendChild($fragment);
},
error: (err) => {
console.log(err);
$table.insertAdjacentHTML("afterend", `<p><b>${err}</b></p>`);
},
});
};
d.addEventListener("DOMContentLoaded", getAll);
</script>
</body>
</html>
El archivo JSON sobre el que trabaja este script es el siguiente:
