Listo (Ctrl + Enter para ejecutar) Bootcamp Fullstack »
index.html
Tab = 4 espacios
1
<!DOCTYPE html>
<html lang="es">
<head>
  <meta charset="UTF-8">
  <title>Fetch API con Async/Await</title>
  <style>
    body { font-family: Arial, Helvetica, sans-serif; padding: 25px; background: #f8fafc; }
    .card-api { max-width: 540px; background: white; border: 1px solid #cbd5e1; border-radius: 8px; padding: 22px; }
    .barra-accion { display: flex; gap: 8px; margin-bottom: 15px; }
    button { padding: 9px 16px; background: #0284c7; color: white; border: none; border-radius: 6px; font-weight: bold; cursor: pointer; }
    button:hover { background: #0369a1; }
    button:disabled { opacity: 0.6; cursor: not-allowed; }
    .indicador { padding: 8px 12px; border-radius: 6px; font-size: 0.85rem; margin-bottom: 12px; }
    .cargando { background: #e0f2fe; color: #0369a1; }
    .error { background: #fee2e2; color: #991b1b; }
    .lista-usuarios { list-style: none; padding: 0; margin: 0; }
    .item-usuario { padding: 10px 12px; border-bottom: 1px solid #e2e8f0; display: flex; justify-content: space-between; align-items: center; }
    .item-usuario:last-child { border-bottom: none; }
    .email-tag { font-size: 0.8rem; color: #64748b; font-family: monospace; }
  </style>
</head>
<body>

  <div class="card-api">
    <h3 style="margin-top: 0; color: #0f172a;">Directorio de Usuarios Externo</h3>

    <div class="barra-accion">
      <button id="btn-cargar" onclick="cargarUsuarios()">Consultar API Externa (JSONPlaceholder)</button>
    </div>

    <div id="caja-estado"></div>
    <ul class="lista-usuarios" id="lista-usuarios"></ul>
  </div>

  <script>
    async function cargarUsuarios() {
      const btn = document.getElementById('btn-cargar');
      const estado = document.getElementById('caja-estado');
      const lista = document.getElementById('lista-usuarios');

      btn.disabled = true;
      lista.innerHTML = "";
      estado.className = "indicador cargando";
      estado.textContent = "⏳ Conectando con servidor remoto vía fetch()...";

      try {
        // Petición asíncrona real con fetch y await
        const respuesta = await fetch('https://jsonplaceholder.typicode.com/users?_limit=4');

        if (!respuesta.ok) {
          throw new Error(`Código de estado HTTP: ${respuesta.status}`);
        }

        const usuarios = await respuesta.json();

        estado.className = "indicador";
        estado.style.background = "#dcfce7";
        estado.style.color = "#166534";
        estado.textContent = `✓ ${usuarios.length} usuarios recibidos correctamente.`;

        // Renderizado en el DOM
        lista.innerHTML = usuarios.map(u => `
          <li class="item-usuario">
            <div>
              <strong>${u.name}</strong><br>
              <span class="email-tag">${u.email}</span>
            </div>
            <span style="font-size: 0.75rem; background: #f1f5f9; padding: 3px 8px; border-radius: 4px;">ID #${u.id}</span>
          </li>
        `).join('');

      } catch (error) {
        estado.className = "indicador error";
        estado.textContent = `✕ Error en la petición: ${error.message}`;
      } finally {
        btn.disabled = false;
      }
    }
  </script>

</body>
</html>
Haz clic para editar este código
Vista Previa
Consola Virtual JavaScript