005. API REST: CRUD con AJAX (1)

Como vimos en capítulos anteriores, en Ajax hay varios pasos que seguir:

  1. Crear la instancia del objeto.
  2. El listener.
  3. Abrir la petición.
  4. 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:

Scroll al inicio