Conecta tu catálogo de productos a un API real con fetch, maneja errores como un profesional y renderiza listado y detalle de forma asíncrona. Aquí verás cómo reemplazar mocks por datos vivos, depurar en el navegador y preparar el terreno para filtros y paginación sin complicaciones.
¿Cómo integrar el listado con un API usando async/await y manejo de errores?
La clave es convertir la inicialización del catálogo a asíncrona, consumir el repositorio desde window y validar la respuesta antes de parsear el JSON. Así garantizas que solo renderizas datos correctos y evitas fallos por content-type inesperado.
Centraliza el acceso al API en un repositorio único.
Valida response.ok antes de response.json().
Verifica el headercontent-type: application/json.
Usa async/await en initializeCatalog y en el listener que la invoque.
Reemplaza el mock por la respuesta del API en renderProducts.
¿Cómo luce el método getProducts con validaciones?
asyncfunctiongetProducts(){const res =awaitfetch(`${BASE_URL}/products`);if(!res.ok){thrownewError('No fue posible encontrar los productos.');}const contentType = res.headers.get('content-type')||'';if(!contentType.includes('application/json')){thrownewError('La respuesta no es JSON.');}returnawait res.json();}
¿Cómo inicializar initializeCatalog con async/await?
asyncfunctioninitializeCatalog(){const repo =window.productRepository;// repositorio disponible en windowconst productResponse =await repo.getProducts();renderProducts(productResponse);// pintar lista desde el API}
Beneficios inmediatos: un único flujo para filtrar por categoría o aplicar paginación, pues todo parte de un mismo método y un solo parámetro de entrada.
¿Cómo depurar y validar respuestas en el navegador?
Usa las herramientas del navegador para confirmar que los datos llegan y dónde fallan si algo sale mal. Con inspeccionar elementos, Sources y un break point, verás la pausa en la ejecución y podrás leer el estado de las variables; con console.log corroboras que llega, por ejemplo, un arreglo de cincuenta y un elementos. En Network, activa preserve logs para ver cada petición, su endpoint y la estructura del response.
Abre Sources y coloca un break point en el repositorio y en la vista.
Lanza await repo.getProducts() desde la consola para probar.
Revisa Network y confirma el endpoint: api/v1/products.
Observa el response y su estructura antes de renderizar.
Mantén un console.log temporal para facilitar el debugging.
Sugerencia práctica: quita impresiones y break points una vez validado el flujo para no contaminar la consola.
¿Cómo obtener y renderizar el detalle con getProduct(id)?
Para el detalle, añade un método en el repositorio que reciba el ID y consulta el endpoint de un único recurso. Haz asíncronos initializeDetail y loadProductDetail, obtén el repositorio desde window y maneja el estado cuando no haya datos.
¿Cómo se implementa getProduct(id) en el repositorio?
asyncfunctiongetProduct(id){const res =awaitfetch(`${BASE_URL}/products/${id}`);if(!res.ok){thrownewError('No fue posible obtener el producto.');}const contentType = res.headers.get('content-type')||'';if(!contentType.includes('application/json')){thrownewError('La respuesta no es JSON.');}returnawait res.json();}
¿Cómo cargar el detalle con initializeDetail y loadProductDetail?
asyncfunctioninitializeDetail(){// productId ya validado previamente en la vistaawaitloadProductDetail(productId);}asyncfunctionloadProductDetail(productId){const repo =window.productRepository;const currentProduct =await repo.getProduct(productId);if(!currentProduct){// Muestra el estado de error definido en el template.return;}// Pinta la información del producto en el template.}
Puntos finos que evitarán errores:
No reescribas una const en JavaScript: respeta su inmutabilidad.
Elimina bloques heredados del template que ya no se usan al consumir el API.
Verifica en Network que se llama al endpoint correcto, por ejemplo api/v1/products/:id, pasando el ID como query param o segmento según la definición disponible.
Observa nuevos campos útiles en la respuesta, como la fecha de creación, para enriquecer la vista cuando existan.
Próximos pasos que potencian la integración:
Crea un repositorio de categorías y lista categorías para el template.
Usa URLSearchParams para filtros y paginación en el listado.
¿Tienes dudas sobre el patrón de repositorio, el manejo de errores o el uso de async/await? Comparte tu pregunta y cuéntame qué parte te gustaría profundizar.
asíncrono se refiere a operaciones que no bloquean la ejecución del programa. Por ejemplo, al hacer una solicitud de red (como fetch), el código puede seguir ejecutándose mientras espera la respuesta. La clase explica cómo usar async/await para manejar estas operaciones de forma más legible.
# **Codigo Repository.js**
El Archivo definido como ./public/js/repositories.js define una clases ProductRepository que es un patron de diseño de software "Repository" usado para separar la logica que trae datos desde la fuete "La flake api de /prodcuts" hacia la logica de negocios que actua en los datos, ewscencialmente esta clase acrua como un data manager dedicado para 'products' se encarga de todas la comunacion con el backend de la fake api.
## Metodo getProducts( categoriyId ) { }
Propósito: Obtener una lista de todos los productos de la API. Opcionalmente, se pueden filtrar por categoryId.
async: Esta palabra clave indica que la función realizará una operación asíncrona (como una llamada a la API) y devolverá una promesa.
URLSearchParams: Esta es una utilidad integrada del navegador para crear fácilmente cadenas de consulta de URL. Si se proporciona un categoryId, se añade a los parámetros (p. ej., ?categoryId=1).
Construcción de URL: Comienza con la URL base, añade el punto final /products/ y, a continuación, añade los parámetros de filtro, si existen.
await fetch(url): Este es el núcleo del método. Envía una solicitud GET a la URL de la API construida y espera la respuesta inicial del servidor.
Gestión de errores: Comprueba si la respuesta no fue correcta (!response.ok). Sin embargo, la lógica presenta un error. La condición !response.headers.get('content-type') != 'applicacion/json' es una doble negación y contiene un error tipográfico (applicacion). Intenta comprobar el tipo de contenido, pero no lo hace correctamente.
await response.json(): Si la solicitud es exitosa, esta línea lee el cuerpo de la respuesta y lo analiza como JSON.
return responseData: Devuelve la matriz de objetos del producto.
## Metodo getProduct( id ) { }
Propósito: Obtener un producto único usando su ID único.
Construcción de URL: Crea la URL añadiendo "/products/" y el ID del producto específico a la URL base (p. ej., .../api/v1/products/84/).
await fetch(...): Envía una solicitud GET para ese producto específico.
Manejo de errores: Esta sección también contiene errores.
El primer if tiene la misma lógica errónea que getProducts.
La condición else if es incorrecta: contentType.includes('application/json'). Esto genera un error si la respuesta es JSON, lo cual es lo opuesto al comportamiento deseado. Debería generar un error si la respuesta no es JSON.
await response.json(): Analiza la respuesta correcta en un objeto de producto.
return responseData: Devuelve el objeto de producto único.