006. API REST: CRUD con AJAX (2)

En el capítulo anterior dejábamos a la mitad el CRUD sobre el que estamos trabajando, y tan sólo leíamos los datos de nuestro archivo JSON. En este capítulo vamos a finalizar el ejercicio. Mostrábamos como logramos hacer una función denominada ajax() que contemplara todos los pasos que hay que necesitar activar para que una petición XMLHttpRequest funcione, y comprobábamos como funcionaba con la solicitud GET, que es la lectura de ese CRUD.

En este capítulo veremos el resto de operaciones, es decir, el CREATE, el UPDATE y el DELETE, y como toda la sintaxis se va a simplificar gracias a la función ajax() creada en el capítulo anterior.

La creación y la edición a nivel de eventos tendrá que ejecutarse a la hora de procesar el formulario del capítulo anterior, el cual teníamos guardado en la variable form.

Veamos la nueva sintaxis.

<!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="text"
            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);

      d.addEventListener("submit", (e) => {
        if (e.target === $form) {
          e.preventDefault();
          if (!e.target.id.value) {
            // Create POST
            ajax({
              url: "http://localhost:5555/santos",
              method: "POST",
              success: (res) => {
                location.reload();
              },
              error: () => {
                $form.insertAdjacentElement("afterend", `<p><b>${err}</b></p>`);
              },
              data: {
                nombre: e.target.nombre.value,
                constelacion: e.target.constelacion.value,
              },
            });
          } else {
            // Update PUT
            ajax({
              url: `http://localhost:5555/santos/${e.target.id.value}`,
              method: "PUT",
              success: (res) => {
                location.reload();
              },
              error: () => {
                $form.insertAdjacentElement("afterend", `<p><b>${err}</b></p>`);
              },
              data: {
                nombre: e.target.nombre.value,
                constelacion: e.target.constelacion.value,
              },
            });
          }
        }
      });

      d.addEventListener("click", (e) => {
        if (e.target.matches(".edit")) {
          $title.textContent = "Editar nombre";
          $form.nombre.value = e.target.dataset.name;
          $form.constelacion.value = e.target.dataset.constellation;
          $form.id.value = e.target.dataset.id;
        }

        if (e.target.matches(".delete")) {
          let isDelete = confirm(
            `¿Estás seguro de eliminar el id ${e.target.dataset.id}?`
          );

          if (isDelete) {
            // Delete - DELETE
            ajax({
              url: `http://localhost:5555/santos/${e.target.dataset.id}`,
              method: "DELETE",
              success: (res) => location.reload(),
              error: () => alert(err),
            });
          }
        }
      });
    </script>
  </body>
</html>
Scroll al inicio