Recomiendo colcoar los query parameters en una variable de manera ordenada en un array:
querystring = [
'?',
'limit=3',
'&order=Desc',
].join('');
const URL = `https://api.thecatapi.com/v1/images/search${querystring}`;
Conceptos fundamentales
¿Qué es una API REST?
Flujo de comunicación entre usuarios, frontend y backend
Primeros pasos con fetch
Consume tu primera API REST
Endpoints y query parameters
¿Qué son los HTTP Status Codes?
¿Qué es una API KEY?
Proyecto
Maquetación del proyecto
¿Qué son los Métodos HTTP?
GET: leyendo michis favoritos
POST: guardando michis favoritos
Consultas a la API para escribir HTML dinámico
DELETE: borrando michis favoritos
Headers en peticiones HTTP
¿Qué son los Headers HTTP?
Header de autorización
Header de Content-Type
FormData: publicando imágenes de michis
Bonus
Axios: librerías de JavaScript para consumir APIs
CORS, caché, redirect y tu propio clon de fetch
GraphQL, Web Sockets y Web 3.0: el mundo más allá de REST
Próximos pasos
Toma el Curso Práctico de Consumo de API REST con JavaScript
No tienes acceso a esta clase
¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera
Juan David Castro Gallego
Aportes 90
Preguntas 9
Recomiendo colcoar los query parameters en una variable de manera ordenada en un array:
querystring = [
'?',
'limit=3',
'&order=Desc',
].join('');
const URL = `https://api.thecatapi.com/v1/images/search${querystring}`;
We can reduce the code usign getElementsByClass or Tag Name
const btn = document.querySelector('button');
async function callUrls() {
const catUrlApi = "https://api.thecatapi.com/v1/images/search?limit=3";
const response = await fetch(catUrlApi);
const data = await response.json();
const images = document.getElementsByTagName("img");
const arrImages = [...images];
arrImages.forEach((image, item) => {
image.src = data[item].url;
});
}
btn.addEventListener("click", callUrls);
window.onload = callUrls();
✌🏻😎
Si les pasa como a mí, que al usar el query parameter les trae siempre 10 sin importar cuantas pidieron, parece que esto sucede cuando le hacen una petición sin usar una API Key.
Cuando llegué a la clase 6, donde explican como usar una API Key noté que al usarla ya me trae la cantidad específica en vez de ser siempre 10.
Cambie un poco la funcionalidad.
Este tema de parámetros y endpoint no es muy dificil de entender, solo hay que ponderle un poco de lógica:
Los **Endpoint **son las rutas por la cual la API recibe una petición. Se llaman “endpoint” (punto final) porque es la última palabra que se escribe en la ruta de la API. Esto lo hacen para poder dividir la API en varias partes y poder consultarla dependiendo de qué consulta le quieres hacer a la api. Normalmente estas están nombradas dependiendo del tipo de información que devuelven. Ej:
https://api.ruta/categorias
https://api.ruta/imagenes
https://api.ruta/favoritos
Los query parameters (parámetros de consulta), son atributos adicionales que le podemos pasar al endpoint para poder filtrar, especificar o limitar la información que queremos obtener del API en ese endpoint. La forma de pasarselo es agregando al final del endpoint un signo de interrogación “?”, y luego ingresar el nombre del parámetro y su valor tipo “key=value”. Se pueden pasar varios parámetros al tiempo separandolos por un signo ampersand “&”. Ej:
https://api.ruta/categorias?pagina=3&cantidad=10&orden=ascendente
Manipulando un poco el DOM con JavaScript 😅
const app = document.getElementById("app");
const btn = document.querySelector("button");
const URL_API = "https://api.thecatapi.com/v1/images/search?limit=3";
const reset = () => {
while (app.firstChild) {
app.removeChild(app.firstChild);
}
};
const getData = async () => {
reset();
const data = await (await fetch(URL_API)).json();
data.map((item) => {
const img = document.createElement("img");
const figure = document.createElement("figure");
img.src = item.url;
figure.appendChild(img);
return app.append(figure);
});
};
getData();
btn.onclick = () => getData()
Un endpoint de API es un punto en el que una API, el código que permite que dos programas de software se comuniquen entre sí, se conecta con el programa de software. Las API funcionan enviando solicitudes de información desde una aplicación web o un servidor web y recibiendo una respuesta .
En otras palabras, los endpoints de API son la ubicación digital específica donde un programa envía solicitudes de información para recuperar el recurso digital que existe allí. Los endpoints especifican dónde las API pueden acceder a los recursos y ayudan a garantizar el correcto funcionamiento del software incorporado. El rendimiento de una API depende de su capacidad para comunicarse correctamente con los puntos finales de la API.
Los programas de software suelen tener endpoints. Por ejemplo, en Instagram incluyen uno que permite a las empresas y los creadores medir las interacciones de medios y perfiles; uno que les permita moderar los comentarios y sus respuestas; y una tercera que les permite descubrir medios etiquetados.
Query params
El query param es la clave valor name=oscar
que vemos al final de la URL, y como regla, siempre deberán estar después del símbolo de interrogación. Además, una URL puede tener N query params, cómo el siguiente ejemplo:
https://myapi.com/customers?firstname=oscar&lastname=blancarte&status=active
Esta URL la podemos utilizar para buscar a todos los clientes donde su nombre es oscar, su apellido es blancarte y su estatus es activo. Cuando utilizamos más de un Query param, es importante separar cada uno mediante el simbolo &
.
Por si a alguien le interesa les dejo una manera muy sencilla de implementar un infinite scroll como el que nos podemos encontrar en aplicaciones actuales. En lugar de tener un botón para cargar más imágenes tenemos un listener que escucha el scroll de la página.
En el html no tendremos que poner ninguna imagen, solamente un contenedor donde se cagarán las imágenes por medio de JavaScript.
<!doctype html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Gatitos Aleatorio</title>
</head>
<body>
<div>
<h1>Gatitos aleatorios</h1>
</div>
<div id="container">
</div>
<script src="./main.js"></script>
</body>
</html>
El código en JavaScript es muy similar al de la clase solo que en lugar de agregar el src a las imágenes previamente creadas en el html en este caso las creamos con el método createElement y posteriormente las agregamos al div con id container con el método appendChild.
En lugar de tener un evento onclick en un botón tenemos un listener que escucha el scroll de la página y en el momento en que calcula que estamos al final de la página hace la petición de más imágenes.
// En este caso cargo de 8 en 8 pero se puede variar sin ningún problema
// lo único a tener en cuenta es que tiene que haber las suficientes en
// la primera carga como para que se genere un scroll, puesto que si ponemos
// por ejemplo solo 2 en una pantalla algo grande no generan un scroll porque
// caben de sobra. Y nuestro listener solo es llamado cuando hacemos scroll
// en la pantalla.
const URL = 'https://api.thecatapi.com/v1/images/search?limit=8';
// Container donde cargaremos las imágenes
const container = document.getElementById('container');
const fetchImages = async () => {
try {
const res = await window.fetch(URL);
const data = await res.json();
// Creamos un bucle for que lee todas las imágenes de la petición
// Al ser dinámico podemos variar el limit de la petición sin
// tener que modificar la lógica o el html
data.forEach(image => {
// Esta es otra manera de crear un elemento html en JavaScript
const img = document.createElement("img");
img.src = image.url;
img.alt = 'Foto gatito aleatorio';
img.width = 500;
img.height = 500;
// Agregamos un nuevo hijo a nuestro contenedor
container.appendChild(img);
})
} catch (error) {
console.error(error);
}
}
// Petición inicial de imágenes
fetchImages();
const onScroll = () => {
// Solo pasa el if si cumple la condición de estar al final de nuestra página
if (document.body.scrollHeight - window.innerHeight <= window.scrollY) {
console.log('Estoy en el final del Scroll!!');
// Como estamos en el final del scroll hacemos de nuevo la petición de imágenes
fetchImages();
}
}
// Esto es un listener que escucha el scroll de la página y llama a la función
// onScroll que creamos previamente
window.addEventListener('scroll', onScroll);
Espero les sea de ayuda, les dejo mi web www.jcoder.es donde subo algunos tutoriales de programación y fotografía, les agradecería se pasaran y me dieran feedback para poder mejorarla.
Gracias.
Esta es mi pequeña implementación usando JS para hacer integración con el usuario😊
Reto resuelto con perritos! 🐶
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Pacifico&family=Square+Peg&display=swap" rel="stylesheet">
<title>Random Dogs with API REST</title>
</head>
<body>
<header>
<h1>Random Dogs</h1>
</header>
<section class="container">
<img id="img1" alt="Dog Random Picture" class="image">
<img id="img2" alt="" class="image">
<img id="img3" alt="" class="image">
</section>
<div class= "button-container">
<button type="button" onclick="reload()" class="random-dog-button"> Random Dogs</button>
</div>
<script src="./main.js"></script>
</body>
</html>
CSS
* {
box-sizing: border-box;
margin: 0px;
padding: 0px;
}
html {
font-size: 62.5%;
}
body {
font-family: 'Square Peg', cursive;
}
header {
display: flex;
justify-content: center;
}
h1 {
font-size: 8rem;
}
.container {
display: flex;
flex-direction: row;
justify-content: center;
place-items: center;
padding: 20px;
}
.container .image {
border-radius: 20px;
margin: 5px;
width: 300px;
height: 300px;
}
.button-container {
display: flex;
place-content: center;
}
.random-dog-button {
background-color: rgb(228, 164, 94);
border: 5px solid rgb(249, 151, 66);
border-radius: 15px;
cursor: pointer;
font-family: 'Pacifico', cursive;
font-size: 2rem;
padding: 12px;
width: 200px;
height: auto;
}
.random-dog-button:hover {
border: 5px solid rgb(228, 164, 94);
background-color: rgb(227, 141, 67);
}
JS
const API_URL = "https://api.thedogapi.com/v1/images/search?limit=3";
async function reload() {
const res = await fetch(API_URL)
const data = await res.json()
console.log(data)
const img1 = document.getElementById('img1');
const img2 = document.getElementById('img2');
const img3 = document.getElementById('img3');
//img.src = data[0].url;
img1.src = data[0].url;
img2.src = data[1].url;
img3.src = data[2].url;
}
reload();
Me ha costado un poco mas de lo espero, puesto que la API que estoy usando no admite limit=3 entonces fue un poco mas complicado traer las 3 imagenes al tiempo.
Estoy satisfecho con lo que voy logrando!
Para los que no quieran ponerle ids a los img, hay una solución más simple:
const img = document.querySelectorAll('img')
De esa manera van a poder acceder a todas las imágenes sin necesidad de crear ids
Definitivamente juandc tiene una forma muy entendible de eseñar
Creé una opción para mostrar imágenes estáticas o solamente GIFs:
.
Body del HTML:
<body>
<h1>Gatitos aleatorios</h1>
<div class="imagen--gatitos">
<img alt="Foto gatito aleatoria" /><br/>
<label for="movimiento">Escoge si tus gatos serán estáticos o con movimiento</label>
<select name="movimiento" id="movimiento">
<option value="sin movimiento">Sin movimiento</option>
<option value="con movimiento">Con movimiento</option>
</select>
<button type="button" onclick='fotoGatito()'>Otro gatito :3</button>
</div>
<script src="./main.js"></script>
</body>
Código JS:
const URL = 'https://api.thecatapi.com/v1/images/search';
const movimiento = document.getElementById('movimiento');
let value = "";
const fotoGatito = async () => {
if(movimiento.value == "con movimiento"){
value = "?mime_types=gif";
} else {
value = "";
}
try {
const res = await fetch(URL+value);
const data = await res.json();
const images = document.querySelector('img');
images.src = data[0].url;
} catch {
console.error(new Error('Error: '));
}
}
fotoGatito();
Una forma para hacer la práctica sin tener que crear los elementos html nosotros es haciéndolo con JS como está a continuación, esta función evalúa si ya hay 3 imágenes y las elimina para poner las nuevas
Ingresamos nuestro loader antes de nuestra imagen en el archivo .html y le damos una clase ‘hide’.
<body>
<div id="app">
<p id="loader" class="hide">Cargando imagen</p>
<img width="400" id="img" alt="Foto de perro" />
<button onclick="getImageDog()">Recargar</button>
</div>
<script src="index.js"></script>
</body>
Ahora definimos nuestra clase en el archivo .css que crearemos previamente. De la siguiente manera:
.hide {
display: none;
}
Ahora en JavaScript, cada que le demos al botón, mostrará nuestro loader en lo que cargue la imagen, para saber que algo está sucediendo.
const API_URL = "https://api.thedogapi.com/v1/images/search";
const img = document.getElementById("img");
const loader = document.getElementById("loader");
const getImageDog = async () => {
showOrHide(img, loader);
const data = await (await fetch(API_URL)).json();
showOrHide(img, loader);
img.src = data[0].url;
};
function showOrHide(elementHide, elementoShow) {
elementHide.classList.toggle("hide");
elementoShow.classList.toggle("hide");
}
getImageDog();
Recuerda que tu loader puede ser una animación, un progress bar, un skeleton, etc. Eso dependerá de tu imaginación. Utilicé el párrafo para fines explicativos. Saludos 💚
excelente hasta el momento, ha sido muy digerible l nformacion
Que tal compañeros aqui les dejo mi version del reto.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gatitos Aleatorios</title>
<link rel="stylesheet" href="./styles.css">
</head>
<body>
<header>
<h1>Gatitos aleatorios</h1>
</header>
<div class="container">
<img id="img-cat" alt="Gatitos aleatorios">
<button type="button" id="btn-button">Cambiar imagen</button>
</div>
<script src="./main.js"></script>
</body>
</html>
CSS
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
html{
font-size: 62.5%;
}
header{
display: flex;
justify-content: center;
}
h1{
font-size: 4rem;
}
.container{
display: flex;
flex-direction: column;
justify-content: center;
place-items: center;
padding: 20px;
}
img {
width: auto;
height: 500px;
border-radius: 30px;
}
button{
width: 100%;
min-width: 300px;
padding: 10px;
margin-top: 40px;
font-size: 16px;
border-radius: 15px;
background: #66BB6A;
cursor: pointer;
transition:all;
border: 5px solid #187a1d ;
}
button:hover{
border: 5px solid rgb(228, 164, 94);
background-color: rgb(227, 141, 67);
}
@media screen and (min-width: 1024px) {
button{
width: 20%;
}
}
JAVASCRIPT
//para mandar a llamar una url se hacen los siguientes pasos
const URL = 'https://api.thecatapi.com/v1/images/search'
//mostrar una imagen con boton
async function mycat (){
const res = await fetch(URL);
const data = await res.json();
const img =
document.getElementById('img-cat');
img.src = data[0].url;
}
const myButton = document.getElementById('btn-button')
myButton.onclick = mycat;
El comando de VSC para tener multiples cursores al mismo tiempo es:
Multiples cursores hacia arriba
Ctrl + Shift + ↑
Multiples cursores hacia abajo
Ctrl + Shift + ↓
Mi solución.
No use IDs en las imagenes. Solo la misma clase para usar en CSS
function recargar(url_fetch){
fetch(url_fetch)
.then(res => res.json())
.then(data => {
const img=document.querySelectorAll('img');
for (let i = 0; i < 3; i++) {
img[i].src= data[i].url;
console.log(data[i].url);
}
});
}
El código mas factorizado
const img = document.querySelectorAll("img");
const btn = document.querySelector("button");
const getCatImg = async () => {
const res = await fetch(API_URL);
const data = await res.json();
img.forEach((item, index) => {
item.src = data[index].url;
});
};
getCatImg();
btn.addEventListener("click", getCatImg);
Reto con perritos 🐶🐶
HTML
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Random Dogs</title>
<link rel="stylesheet" href="./main.css">
</head>
<body>
<h1>Random Dogs</h1>
<div class="img-container">
</div>
<button type="button" class="button">Reset</button>
<script src="./main.js"></script>
</body>
</html>
CSS
h1 {
text-align: center;
}
.img-container {
display: grid;
grid-template-columns: repeat(3, 1fr);
width: 600px;
margin: 0 auto;
margin-bottom: 10px;
gap: 10px;
}
.img-container img{
width: 100%;
height: 100%;
object-fit: cover;
}
.button {
display: block;
margin: 0 auto;
width: 400px;
border-radius: 5px;
padding: 5px;
font-size: 20px;
border: 1px solid rgba(0, 0, 0, 0.4);
font-weight: bold;
cursor: pointer;
}
.button:hover {
opacity: 0.8;
}
JavaScript
const button = document.querySelector('.button');
const reload = async () => {
const API_URL = 'https://api.thedogapi.com/v1/images/search?limit=6';
const res = await fetch(API_URL);
const data = await res.json();
const imgContainer = document.querySelector(".img-container");
imgContainer.innerHTML = ""
data.map(img => {
imgContainer.insertAdjacentHTML('afterbegin', `<img id="${img.id}" src="${img.url}">`)
})
};
reload();
button.addEventListener("click", () => {
reload();
});
const API = 'https://api.thecatapi.com/v1/images/search?limit=3'
const fetch_api = async () => {
const request = await fetch(API)
const response = await request.json()
const img = document.querySelectorAll('.img')
img.forEach((image, index) => {
img[index].src = response[index].url
})
}
window.addEventListener('DOMContentLoaded', fetch_api)
const button = document.querySelector('button')
button.addEventListener('click', fetch_api)
Hola comunidad buen dia!
Bueno a mi tambien me paso que al momento de colocar el ‘limit=3’ cuando fui a la consola siempre me daba 10 objetos en el array. Esto pasa porque es necesario usar la API Key
Pues es necesario registrar algunos datos en la parte de las mebresias, luego te envian un correo con tu API Key personal.
Para poder usar esta API Key solo es necesario ponerla justo despues del Endpoint, yo lo hice de esta manera.
const APIKEY = `api_key=live_xTJCEBbcBY5QamZ9lZKBKxAiSZugWwDqoyVhXulXdekwJyEqPb`
const URL = `https://api.thecatapi.com/v1/images/search?${APIKEY}&limit=3`;
Logicamente corte una parte de mi API Key para temas de privacidad.
Espero aportar en algo y sigamos avanzando todos
Hola a todos. Acá les dejo mi solución al tema de la clase.
A diferencia del profe JuanDC, realicé la inserción de las imágenes dinámicamente desde JS con la función map
y el appendChild
a un contenedor de imágenes.
Todo bien hasta ahí peeero debido al appendChild
al recargar las imágenes anteriores no se borraban, por lo tanto, con el ciclo while
antes de la función map
borro dinámicamente el contenido del contenedor, en caso de que exista, para luego realizar la carga de las imágenes nuevas. Ah, y por lo visto la API en este momento solamente permite traer 10 elementos ni más ni menos sin una API-key
.
const container = document.getElementById('container');
const btnReload = document.getElementById('btnReload');
const API_URL = 'https://api.thecatapi.com/v1/images/search?limit=3';
// fetch(API_URL)
// .then(res => res.json())
// .then(data => {
// img.src = data[0].url;
// });
window.addEventListener('DOMContentLoaded', rechargeImage);
btnReload.addEventListener('click', rechargeImage);
async function rechargeImage() {
try {
const response = await fetch(API_URL);
const data = await response.json();
while (container.firstChild) {
container.removeChild(container.firstChild);
}
data.map((item) => {
const img = document.createElement('img');
const figure = document.createElement('figure');
img.src = item.url;
img.width = 150;
img.alt = 'Foto gatito aleatorio';
figure.appendChild(img);
return container.appendChild(figure)
});
} catch (error) {
console.log(error);
}
}
Yo hice una pequeña página con 3 elementos que se actualizan al darle click.
const URL = 'https://api.thecatapi.com/v1/images/search';
const imgContainer1 = document.querySelector("#random-cat1");
const imgContainer2 = document.querySelector("#random-cat2");
const imgContainer3 = document.querySelector("#random-cat3");
const imgContainer = document.querySelector('.cat-container');
async function reloadEvery(apiUrl){
const response = await fetch(apiUrl);
const data = await response.json();
imgContainer1.src = data[0].url;
imgContainer2.src = data[1].url;
imgContainer3.src = data[2].url;
}
async function reloadSingle(apiUrl,container){
const response = await fetch(apiUrl);
const data = await response.json();
document.querySelector(`#${container}`).src = data[0].url;
}
document.addEventListener('DOMContentLoaded',e=>{
reloadEvery(`${URL}?limit=3`);
});
imgContainer.addEventListener('click',e=>{
if(e.target.className === 'cat-image'){
const imageId = e.target.id;
reloadSingle(URL,imageId);
}
})
Les comparto mi solución utilizando map para cargar las imagenes:
const API_URL = 'https://api.thecatapi.com/v1/images/search?limit=3';
const content = null || document.getElementById('content');
const button = document.getElementById('refresh');
async function getCatsFetch(url) {
const response = await fetch(url);
const result = await response.json();
return result;
}
const getImage = async (urlApi) => {
try {
const cats = await getCatsFetch(urlApi);
console.log(cats);
let view = `
${cats.map(item => {
return `
<img width="220" src="${item.url}" alt="${item.id}">
`
}).join('')}
`;
content.innerHTML = view;
} catch (error) {
console.error(error);
}
}
getImage(API_URL);
button.addEventListener('click', () => {getImage(API_URL)});
potente la clase y los aportes 😄
ENDPOINTS:
En el contexto de una API REST, los endpoints son URLs específicas que representan recursos o acciones dentro de un sistema. Cada endpoint se corresponde con una función o método específico que se puede invocar a través de una solicitud HTTP, como GET, POST, PUT o DELETE.
Los endpoints son utilizados para interactuar con los recursos de una API y realizar operaciones como recuperar información, crear nuevos elementos, actualizar o eliminar registros existentes. Cada endpoint está asociado con una ruta única y puede aceptar parámetros en la URL o en el cuerpo de la solicitud para personalizar la operación realizada.
Por ejemplo, supongamos que tenemos una API REST para gestionar una lista de usuarios. Algunos ejemplos de endpoints podrían ser:
GET /users: Devuelve una lista de todos los usuarios.
GET /users/{id}: Devuelve los detalles de un usuario específico identificado por su ID.
POST /users: Crea un nuevo usuario.
PUT /users/{id}: Actualiza los datos de un usuario existente identificado por su ID.
DELETE /users/{id}: Elimina un usuario específico identificado por su ID.
Cada uno de estos endpoints representa una operación específica que se puede realizar en la API, y la combinación de la URL del endpoint y el método HTTP utilizado determina qué acción se llevará a cabo en el sistema.
QUERY PARAMETERS:
Los query parameters (parámetros de consulta) son una forma de pasar información adicional a través de la URL en una solicitud HTTP. Estos parámetros se agregan al final de la URL después del símbolo de interrogación (?), y se componen de pares clave-valor separados por el símbolo de ampersand (&).
Los query parameters permiten personalizar y filtrar los resultados de una solicitud, ya que los valores de los parámetros pueden afectar la forma en que se procesa la solicitud y se devuelve la respuesta. Algunos casos comunes de uso de los query parameters incluyen:
Filtrar resultados: Se pueden especificar criterios de búsqueda para obtener solo los datos que cumplan ciertas condiciones. Por ejemplo, una solicitud a /products?category=electronics podría devolver solo los productos de la categoría “electronics”.
Paginación: Se pueden usar parámetros como page y limit para obtener conjuntos de resultados paginados. Por ejemplo, /products?page=2&limit=10 podría devolver la segunda página de 10 productos.
Ordenamiento: Se pueden especificar parámetros para ordenar los resultados. Por ejemplo, /products?sort=price podría devolver los productos ordenados por precio.
Filtros avanzados: Se pueden usar múltiples parámetros para realizar filtros más complejos. Por ejemplo, /products?category=electronics&price_min=100&price_max=500 podría devolver los productos de la categoría “electronics” con un precio entre $100 y $500.
En el lado del servidor, los query parameters se pueden leer y procesar para realizar acciones específicas en función de los valores proporcionados. Los frameworks y bibliotecas para el desarrollo de APIs generalmente ofrecen facilidades para obtener y trabajar con los query parameters de manera sencilla.
lo hice con la app de ricky a morty y en un card
Para la llamada a las etiquetas img utilice un querySelectorAll, y para agregarle la url a cada una utilice un forEach
.
Revisando los aportes para optimizar y las propuestas encontre una manera mas óptima para el codigo
llamando la clase donde tenia las imgs logro optimizar y repetir codigo:
en html, no necesitaria las clases internas
<section class="multiplesCat">
<img class="cat-1" alt="Gato Aleatorio">
<img class="cat-2" alt="Gato Aleatorio">
<img class="cat-3" alt="Gato Aleatorio">
<img class="cat-4" alt="Gato Aleatorio">
<img class="cat-5" alt="Gato Aleatorio">
<img class="cat-6" alt="Gato Aleatorio">
<img class="cat-7" alt="Gato Aleatorio">
<img class="cat-8" alt="Gato Aleatorio">
<img class="cat-9" alt="Gato Aleatorio">
</section>
en JS
const API_URL = 'https://api.thecatapi.com/v1/images/search?limit=3';
async function moreCats() {
try {
const response = await fetch(API_URL);
const data = await response.json();
console.log(data);
const images = document.querySelectorAll('.multiplesCat img');
console.log(images);
images.forEach((img, index) => {
img.src = data[index].url;
});
} catch (error) {
console.log('Ocurrió un error: ', error);
}
}
moreCats();
Les dejo mi aporte de como implemente la solución al reto que se plantea, lo aprendí en el curso de asincronismo:
.
.
Este es el código:
.
JavaScript
const URL_API = "https://api.thecatapi.com/v1/images/search?limit=100";
const imagesContainer = document.getElementById('images-container')
async function fetchData() {
const response = await fetch(URL_API);
const data = await response.json();
return data;
}
function showMichis() {
(async () => {
try {
const gatitos = await fetchData();
let imgs = `
${gatitos.slice(0, 6).map(data => `
<img
src="${data.url}"
alt="Imagen de un gatito aleatorio">
`).join('')}
`;
imagesContainer.innerHTML = imgs;
} catch (error) {
const showError= `
<div class="cards-error-info">
<h3>
Ups! Ocurrió un error al intentar mostrar los gatitos, inténtalo nuevamente.
</h3>
</div>
`;
imagesContainer.innerHTML = showError;
}
})();
}
showMichis();
.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./styles.css">
<title>Gatitos aleatorios</title>
</head>
<body>
<h1>Gatitos aleatorios</h1>
<button onclick="showMichis()">Recarga el gatito</button>
<div id="images-container">
</div>
<script src="./main.js"></script>
</body>
</html>
.
De esta manera con el catch nos aseguramos de que no solo los errores se pasen por consola, sino que también los puedan ver los usuarios.
Les traigo mi código de implementación de imágenes desde javascript con template literals y solo un render para optimizar la inyección de codigo HTML.
const URL = 'https://api.thecatapi.com/v1/images/search?limit=4'
let divGatos = document.getElementById('imgCats');
let btn = document.querySelector('button');
btn.addEventListener('click',()=>{bringCats()})
async function bringCats(){
let gatos = await getData(URL);
let imgs = [];
for (let gato of gatos){
let template = `<img style='width:300px'src='${gato.url}' alt='imgs de gatos'>`
imgs.push(template)
}
divGatos.innerHTML=imgs.join("")
}
async function getData(urlData){
try{
const res = await fetch(urlData)
const data = await res.json();
return data
}catch(error){
console.log(error)
}
}
bringCats()
Yo lo hice asi:
/*CONSUMO DE API DE GATITOS ALEATORIOS*/
const URL = "https://api.thecatapi.com/v1/images/search";
const body = document.querySelector('body')
const boton = document.querySelector('.generar')
const containerImg = document.querySelector('.containerImg')
boton.style.padding = '15px 20px';
boton.style.cursor = 'pointer';
body.style.display = 'flex';
body.style.flexDirection = 'column'
body.style.justifyContent = 'center'
body.style.alignItems = 'center'
body.style.gap = '18px'
// fetch(URL)
// .then(res => res.json())
// .then(data => {
// const img = document.querySelector('img');
// img.src = data[0].url;
// })
const consumoAPI = async(URLapi)=>{
const response = await fetch(`${URLapi}?limit=1`)
const data = await response.json()
return data;
}
async function init(){
containerImg.innerHTML = "";
let dataImage = await consumoAPI(URL)
console.log(dataImage)
dataImage.forEach((item)=>{
const imgen = document.createElement('img')
imgen.style.width = "200px";
imgen.src = item.url
containerImg.appendChild(imgen)
})
}
init()
boton.addEventListener('click', async(e)=>{
e.preventDefault()
await init();
})
Mi solucion al reto anterior
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Perritos aleatorios</title>
<script src="js/index.js"></script>
</head>
<body>
<h1>Gatitos aleatorios</h1>
<img src="" alt="Fotos de gatitos aleatorios">
<button id="btn">Recargar</button>
</body>
</html>
JavaScript
document.addEventListener("DOMContentLoaded",()=>{
const btn = document.querySelector("#btn");
const url = 'https://api.thecatapi.com/v1/images/search';
const fetchData = (urlApi) =>{
fetch(urlApi)
.then(response => response.json())
.then(data => {
const img = document.querySelector('img');
img.src = data[0].url;
console.log(data[0].url)
});
console.log("Datos consegidos")
}
const getData = async() =>{
try{
console.log("se esta ejecutando")
await fetchData(url);
console.log("fin de ejecucion")
}catch(error){
throw new Error(error);
}
}
btn.addEventListener("click", getData)
})
Aqui les dejos algo a los amantes de las Waifu’s:
Precaucion puede tener material no apto para todo publico, si lo viste fue tu eleccion:
https://github.com/Doni-Metal/random-waifu
Yo creé las imágenes manipulando el DOM desde el JS:
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="src/styles.css">
<title>Gatitos Aleatorios</title>
</head>
<body>
<h1>Gatitos Aleatorios</h1>
<button>Actualizar</button>
<container id="cats-container" class="container">
</container>
<script src="src/reto1.js"></script>
</body>
</html>
JS
const button = document.querySelector('button')
const API = "https://api.thecatapi.com/v1/images/search?limit=3"
async function fetchData(urlApi) {
const response = await fetch(urlApi);
const data = await response.json();
return data
}
const loadImg = async (urlApi) => {
try {
const data = await fetchData(urlApi);
console.log(data, 'data')
const allimg = [];
data.forEach(item => {
console.log(item, 'item de for each')
const image =document.createElement('img');
image.src = `${item.url}`
console.log(image, 'img src')
const card = document.createElement('div')
card.appendChild(image)
allimg.push(card)
const container = document.querySelector('#cats-container')
container.append(...allimg)
});
}
catch(error){
console.error(error)
}
};
loadImg(API)
Manipulando el DOM
const URL_API = "https://api.thecatapi.com/v1/images/search?"
const imageContainer = document.querySelector("#imageContainer")
document.querySelector("#boton").addEventListener("click",element)
document.querySelector("#boton").addEventListener("click",removeImage)
function removeImage(){
[...imageContainer.childNodes].forEach(item =>{
item.remove()
})
}
async function element (){
for(let i =0; i<3; i++){
const response = await fetch(URL_API)
const data = await response.json()
const image = document.createElement('img')
image.src = data[0].url
imageContainer.appendChild(image)
}
}
element()
He querido hacer que las 3 imágenes se creen de forma automática en vez de hard codeadas. He usado un for para iterar el número de elementos dentro de ‘data’ y por cada vuelta he hecho que genere una imagen con un atributo ‘style’ y algunos estilos para que todas tengan el mismo tamaño, por último con un .append() las inyecto dentro de un div (en el archivo index.html) con id ‘imagenesContainer’. No se si es la mejor forma de hacerlo pero lo importante es que sin ayuda he hecho que funcione. Espero que a alguien más le sirva 😃
Aquí dejo mi aporte para que funcione de manera flexible, variando el límite.
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Gatitos aleatorios</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Gatitos aleatorios</h1>
<main>
</main>
<button onclick="createImages()">Recargar</button>
<script src="main.js"></script>
</body>
</html>
const totalCats = 10;
const URL = `https://api.thecatapi.com/v1/images/search?limit=${totalCats}`;
const createImages = async() =>{
const response = await fetch(URL);
const jsonResponse = await response.json();
const imgs=[];
jsonResponse.map(image =>{
const img = document.createElement("img");
img.src=image.url
imgs.unshift(img);
})
document.querySelector('main').replaceChildren(...imgs);
}
createImages();
Les comparto mi pequeño ejercicio, hice tres columnas y el boton de agregar mas imagenes tiene position: fixed para que puedas agregar mas sin importar en que parte de la pagina estes.
Aqui un funcion para realizar la tarea de traer una cantidad determinada de imagenes de gaticos y mostrarla al usuario
// funcion para mostrar una cantidad determinada de imagenes de gatos
const content = null || document.getElementById('ViewGatos')
async function gaticos(){
let cant = cantidad.value
const response = await fetch(`${API}/?limit=${cant}`)
const data = await response.json()
console.log(data)// hacer un for para aggrar las imagenes que lleguen del response.
let view = `
${data.map(elemnt =>
`
<img src=${elemnt.url} width="333px" alt="Imagenes de gaticos aleatorios">
`
).join(' ')}`;
content.innerHTML = view;
}
Boton!!!
window.addEventListener('DOMContentLoaded', catRandom);
const button= document.getElementById("button-change-cat");
button.addEventListener("click", catRandom)
function catRandom(){
const endpoint="https://api.thecatapi.com/v1/images/search"
fetch(endpoint) //devuelve una promesa el fetch hace peticiones a la api
.then(response => response.json())//convertir la respues a algo que js pueda entender ( un objeto por ejemplo)
.then(data =>{
const img = document.querySelector("img");
img.src=data[0].url; //modificarle la propiedad src
});
}
Yo puse el botón de esta manera en HTML:
<button
onClick=“window.location.reload();”>Refresacar
</button>
Y automáticamente se refresca la página. No tuve que hacer código en Javascript.
console.log("hello");
const URL = "https://api.thedogapi.com/v1/images/search?limit=3";
const fetchData = async (urlApi) => {
const res = await fetch(urlApi);
const data = await res.json();
return data;
};
async function anotherFn (){
try {
const listData = await fetchData(URL);
console.log(listData);
const img1 = document.getElementById('img1');
const img2 = document.getElementById('img2');
const img3 = document.getElementById('img3');
img1.src = listData[0].url;
img2.src = listData[1].url;
img3.src = listData[2].url;
} catch (error) {
console.log(error);
}
};
anotherFn();
Les dejo mi solución para poder cargar la cantidad de imágenes que se quiera independientemente del valor de limit. Si se les ocurre algún aporte o alguna mejora me dicen! Gracias 💚
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./styles.css">
<title>Random Cats</title>
</head>
<body>
<h1>Random Cats</h1>
<div class="wrapper-container">
<div class="wrapper">
<div id="image-container" class="image-container">
</div>
<div class="btn-wrapper">
<button class="button" onclick="getRandomCat()">Random Cat</button>
</div>
</div>
</div>
<script src="./main.js"/>
const API = "https://api.thecatapi.com/v1/images/search";
const API_LIMIT = "https://api.thecatapi.com/v1/images/search?limit=3";
async function getCatUrl(urlApi) {
const response = await fetch(urlApi);
const data = await response.json();
return data;
}
function setImg(index) {
let parent = document.getElementById("image-container");
let img = document.getElementById(`img${index}`);
if (img === null) {
img = document.createElement("img");
img.setAttribute("id", `img${index}`);
img.classList.add("cat-img");
parent.appendChild(img);
}
return img;
}
async function getRandomCat() {
let cats = await getCatUrl(API_LIMIT);
for (let index = 0; index < cats.length; index++) {
let img = setImg(index);
img.src = cats[index].url;
}
}
Dejo un codepen usando una animacion de carga hasta que la imagen este lista 👌.
Me gusta muchisimo la camisa de Juan 😦
Cabe mencionar que la traducción de Query es “Consulta”
Esta es la solución que se me ocurrió para no tener que crear tantos etiquetas IMG e ir asignando una por una.
async function fetchData(){
const response = await fetch(API);
const data = await response.json();
const div = document.querySelector('div');
let images = []
for (const ele of data.message) {
const img = `
<img src='${ele}' alt='${ele}'/>
`;
images.push(img);
}
div.innerHTML = images
}
const API_URL=" https://api.thedogapi.com/v1/images/search?limit=3"
async function reload(){
const res = await fetch(API_URL) //cargas la API
const data = await res.json(); //traes la información de la API en Json
const img1 = document.getElementById('img1');//le asignas un valor a img1 del html
const img2 = document.getElementById('img2');
const img3 = document.getElementById('img3');
img1.src = data[0].url //cargas la información de data a esa img1.src
img2.src = data[1].url
img3.src = data[2].url
};
reload();
Que gran clase!
Excelente campeon, vamos genial hasta ahora. Si se puede.
<body>
<h1>API REST, Reference</h1>
<div class="container">
<img id="randomImg" src="" alt="">
<label for="getImages">Choise</label>
<select name="getImages" id="getImages">
<option value="New Image">get new image</option>
<option value="Gif Image">get gif image</option>
</select>
<button type="button" class="primary_button" onclick="randomImage()">Get Image</button>
</div>
<div class="container">
<div id="randomImages"></div>
<input type="number" id="getImgNumber">
<button onclick="reloadNewImages()">Get Images</button>
</div>
<script src="./src/main.js"></script>
</body>
const getImages = document.getElementById('getImages');
let value = '';
// async function fetchRandomImg() {
// const response = await fetch(`${URL_API}`);
// const data = await response.json();
// console.log(data);
// getImage.src = data[0].url
// getImage.src = data.image
// }
// fetchRandomImg();
// btnReload.addEventListener('click', fetchRandomImg);
// async function reloadGif() {
// const response = await fetch()
// }
async function randomImage() {
if (getImages.value == 'Gif Image') {
// alert('getImages');
value = '?mime_types=gif';
} else {
value = '';
}
try {
const response = await fetch(URL_API + value)
const data = await response.json();
const images = document.getElementById('randomImg');
images.src = data[0].url;
} catch (err) {
console.log(new Error(err.message));
alert(err.message);
}
}
randomImage();
const fetchImages = async (url_api) => {
try {
const response = await fetch(url_api);
const data = await response.json();
const images = document.getElementById('randomImages');
images.innerHTML = '';
for (let i = 0; i < data.length; i++) {
const url_image = data[i].url;
images.innerHTML += `<img src= ${url_image}>`
}
} catch (err) {
console.log(new Error(err.message));
}
}
function reloadNewImages() {
const getImgNumber = document.getElementById('getImgNumber');
const valueInput = getImgNumber.value;
fetchImages(`${URL_API}?limit=${valueInput}`);
}
reloadNewImages();
Vamos por mas. Saludos
Tambien podemos tener una constante para la Api sin Query parameter y crear otra constante usando Backticks y el query parameter añadido:
const API_URL = "https://api.thedogapi.com/v1/images/search";
const API_queryParameter = `${API_URL}?limit=3`;
O tambien Podemos poner el query parameter dentro de la funcion usando Backticks:
const API_URL = "https://api.thedogapi.com/v1/images/search";
async function getDog() {
const response = await fetch(`${API_URL}?limit=3`); // <--- De esta manera
const data = await response.json();
const img1 = document.getElementById('img1');
const img2 = document.getElementById('img2');
const img3 = document.getElementById('img3');
img1.src = data[0].url;
img2.src = data[1].url;
img3.src = data[2].url;
}
getDog()
Quise probarlo usando querySelectorAll:
const URL = "https://api.thedogapi.com/v1/images/search?limit=3"
const botonRe = document.querySelector('button');
async function cargarImagen(){
try {
const llamarAPI = await fetch(URL);
const promersaAJSON = await llamarAPI.json();
const imagen = document.querySelectorAll('img');
for (let index = 0; index < imagen.length; index++) {
imagen[index].src = promersaAJSON[index].url;
}
} catch (error) {
alert(`Se rompió algo gato: ${error}`)
}
}
botonRe.onclick = () => {
cargarImagen();
}
cargarImagen();
Yo resolví así lo del botón:
//HTML
<button type="button" id="anotherCat">Random Cat</button>
//JS
const input = document.getElementById('anotherCat');
input.onclick = getCat;
Les comparto mi código. Decidí crear un contenedor en el HTML y que se agregue un <img />
nuevo por cada imagen que llegue en la data, así no se tienen que agregar manualmente al HTML ni agregar id
, necesariamente.
JavaScript:
HTML:
Les comparto mi código para está clase, tiene algunas diferencia con el código del profesor.
Use un bucle para añadir todas las imágenes que se especifique en la variable queryParameter y agregué algunos aportes que encontré en la comunidad, espero les sirva.
const endpoint = 'https://api.thecatapi.com/v1/images/search'
const queryParameter = [
'?',
'limit=3'
].join('')
const API = endpoint + queryParameter
const randomImage = async (url_api) => {
try {
const res = await fetch(url_api)
const data = await res.json()
const imagesWrapper = document.querySelector('.images-wrapper')
imagesWrapper.innerHTML = ''
for (let i = 0; i < data.length; i++) {
const url_img = data[i].url;
imagesWrapper.innerHTML += `<img width="300" src="${url_img}">`
console.log[data[i]]
}
} catch (err) {
console.log(err)
}
}
const button = document.querySelector('button')
button.addEventListener('click', function() {
randomImage(API)
})
randomImage(API)
Otra forma de seleccionar todas las imágenes y manipularlas como un array seria de la siguiente manera.
const API_URL = [
'https://api.thedogapi.com/v1/images/search',
'?limit=3'
].join('');
async function reload(){
const res = await fetch(API_URL);
const data = await res.json();
const img = document.querySelectorAll('img');
img.forEach((item, index) => {
item.src=data[index].url;
});
}
lo aprendí en el curso de Manipulación de Arrays en JavaScript
Como no sé cuántos caracteres puede traer la próxima consulta, mi solución crea los objetos dinámicamente según la cantidad de datos obtenidos. Además agrega los botones también acorde a la página actual.
const URLBASE = "https://rickandmortyapi.com/api/character/";
async function getFemaleChars(page=1) {
queryStr = [
"?page=",
page,
"&gender=female"
];
const response = await fetch(URLBASE + queryStr.join(''));
const data = await response.json();
const results = data.results;
const mainContent = document.querySelector('main');
mainContent.innerHTML = '';
results.map(character =>{
const divContent = document.createElement('div');
const imgContent = document.createElement('img');
const pContent = document.createElement('p');
imgContent.src = character.image;
pContent.textContent = character.name;
divContent.appendChild(imgContent);
divContent.appendChild(pContent);
mainContent.appendChild(divContent);
});
const footerContent = document.querySelector('footer');
footerContent.innerHTML = '';
if (page > 1) {
const prevPage = document.createElement('button');
prevPage.textContent = "Previous Page";
prevPage.addEventListener('click', () => getFemaleChars(page-1));
footerContent.appendChild(prevPage);
}
if (page < data.info.pages) {
const nextPage = document.createElement('button');
nextPage.textContent = "Next Page";
nextPage.addEventListener('click', () => getFemaleChars(page+1));
footerContent.appendChild(nextPage);
}
}
window.onload = getFemaleChars();
HTML
<body>
<img alt="Foto de gatito" style="width:600px">
<img alt="Foto de gatito 2" style="width:600px">
<img alt="Foto de gatito 3" style="width:600px">
<button onclick="pickACat()">Pick another CAThino</button>
<script src="main.js"></script>
</body>
JS
cconst API_URL =
"https://api.thecatapi.com/v1/images/search?limit=3&page=1&api_key=your-api-key";
const pickACat = async (url = API_URL) => {
const response = await fetch(url);
const data = await response.json();
const imgTags = document.querySelectorAll("img");
imgTags.forEach((element, key) => (element.src = data[key].url));
};
pickACat();
hay vamos probando, la hice con cinco y si me salio que bueno es cuando si te sale… esta básico pero me gusta.
Mi solución
HTML
<body>
<h1 class="title">Consumiendo mi primera API</h1>
<button onclick="getCat()">Click me</button>
<div class="img_container">
<div id="img"> </div>
<div id="img"> </div>
<div id="img"> </div>
</div>
<script src="./src/main.js"></script>
</body>
JS
const API_URL = "https://api.thecatapi.com/v1/images/search?limit=3";
async function getCat(){
const res = await fetch(API_URL);
const data = await res.json();
const urlImg = data[0].url;
// const imgs = document.querySelectorAll('#img').style.backgroundImage = `url(${data[0].url})`;
const imgs = document.querySelectorAll('#img');
imgs.forEach((image, item)=>{
image.style.backgroundImage = `url(${data[item].url})`
});
}
getCat();
Así va mi proyecto al momento 😀
.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Perritos aleatorios</title>
<link rel="stylesheet" href="./styles.css" />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;300;400;700&display=swap"
rel="stylesheet"
/>
</head>
<body>
<h1>Perritos aleatorios</h1>
<div class="cards__container">
<section class="card">
<p class="card__title" id="title"></p>
<img id="img1" class="card__img" alt="Foto perrito aleatorio" />
<div class="card__info">
<p class="weight" id="weight"></p>
<p class="height" id="height"></p>
<p class="life-span" id="lifeSpan"></p>
</div>
</section>
<section class="card">
<p class="card__title" id="title"></p>
<img id="img2" class="card__img" alt="Foto perrito aleatorio" />
<div class="card__info">
<p class="weight" id="weight"></p>
<p class="height" id="height"></p>
<p class="life-span" id="lifeSpan"></p>
</div>
</section>
<section class="card">
<p class="card__title" id="title"></p>
<img id="img3" class="card__img" alt="Foto perrito aleatorio" />
<div class="card__info">
<p class="weight" id="weight"></p>
<p class="height" id="height"></p>
<p class="life-span" id="lifeSpan"></p>
</div>
</section>
</div>
<button id="button">¡Ver más perros!</button>
<script src="./main.js"></script>
</body>
</html>
JS
const API_URL = "https://api.thedogapi.com/v1/images/search?limit=3";
const images = document.getElementsByTagName("img");
const titles = document.getElementsByClassName("card__title");
const weights = document.getElementsByClassName("weight");
const heights = document.getElementsByClassName("height");
const lifeSpan = document.getElementsByClassName("life-span");
const button = document.getElementById("button");
async function getDogs() {
const res = await fetch(API_URL);
const data = await res.json();
for (let i = 0; i < data.length; i++) {
images[i].src = data[i].url;
if (data[i].breeds[0]) {
titles[i].innerText = data[i].breeds[0].name;
weights[i].innerText = "Peso: " + data[i].breeds[0].weight.metric + " kg";
heights[i].innerText =
"Altura: " + data[i].breeds[0].height.metric + " cm";
lifeSpan[i].innerText =
"Esperanza de vida: " + data[i].breeds[0].life_span;
} else {
titles[i].innerText = "Sin información";
weights[i].innerText = "Peso: Sin información";
heights[i].innerText = "Altura: Sin información";
lifeSpan[i].innerText = "Esperanza de vida: Sin información";
}
}
}
button.onclick = getDogs;
getDogs();
Asi va mi codigo, aunque no se si es necesario utilzar el try y el catch
const URL = "https://api.thecatapi.com/v1/images/search?limit=4";
const htmlImages = document.getElementsByClassName("cat");
const imgs = [...htmlImages];
const fetchData = async () => {
try{
const response = await fetch(URL);
const data = await response.json();
imgs.forEach((img, index) => {
img.src = data[index].url;
})
}catch(error){
console.error(error);
}
};
document.addEventListener("DOMContentLoaded", fetchData);
const button = document.getElementById("reload");
button.addEventListener("click", fetchData);
Hice el código del profesor, pero en Typescript y usando foreach para colocar el url en cada etiqueta img.
import { Cat } from "./../../models/cat.model";
const URL: string = "https://api.thecatapi.com/v1/images/search?limit=5";
const images: NodeListOf<HTMLImageElement> = document.querySelectorAll("img");
const button: HTMLElement | null = document.getElementById("boton");
async function updateImages (): Promise<void> {
const res: Response = await fetch(URL);
const data: Cat[] = await res.json();
images.forEach((image: HTMLImageElement, index: number) => {
image.src = data[index].url;
});
};
updateImages();
if (button!== null) {
button.onclick = updateImages;
}
Para el boton yo use la propiedad location.reload que te recarga la pagina automaticamente
const btn = document.querySelector(".btn");
btn.addEventListener("click", () => {
location.reload();
});
La pagina esta desactualizada por lo que no se pude hacer de 3 imágenes así que lo hice en predeterminado
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Pacifico&family=Square+Peg&display=swap" rel="stylesheet">
<title>Random Cats with API REST</title>
</head>
<body>
<header>
<h1>Random Cats</h1>
</header>
<section class="container_img">
<!-- Content: Figure + img -->
<!-- <img alt="Cat random Picture" class="image"> -->
</section>
<section class="container">
<button type="button" class="random-cat-button"> Show me a cat!</button>
</section>
<script src="./main.js"></script>
</body>
</html>
CSS
* {
box-sizing: border-box;
margin: 0px;
padding: 0px;
}
html {
font-size: 62.5%;
}
body {
font-family: 'Square Peg', cursive;
}
header {
display: flex;
justify-content: center;
}
h1 {
font-size: 8rem;
}
.container {
display: flex;
flex-direction: column;
justify-content: center;
place-items: center;
padding: 20px;
}
.container_img {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(160px, 100%), 1fr));
gap: 1rem;
width: 80vw;
margin: 1rem auto;
}
img {
width: 100%;
height: 100%;
}
.random-cat-button {
align-items: center;
background-color: rgb(228, 164, 94);
border: 5px solid rgb(249, 151, 66);
border-radius: 15px;
cursor: pointer;
font-family: 'Pacifico', cursive;
font-size: 2rem;
padding: 12px;
width: 200px;
height: auto;
}
.random-cat-button:hover {
border: 5px solid rgb(228, 164, 94);
background-color: rgb(227, 141, 67);
}
JavaScript
querystring = [
'?',
'limit=3',
'&order=Desc',
].join('');
const API_URL = `https://api.thecatapi.com/v1/images/search${querystring}`;
async function myCat () {
const res = await fetch(API_URL);
const data = await res.json();
console.log(data)
//Agregamos las img de las apis en el html
const Container = document.querySelector('section')
Container.innerHTML='';
data.map((img) => {
const content = document.createElement('figure')
content.innerHTML = `<img src="${img.url}" alt="Figures Random cats" />`;
Container.append(content);
})
}
myCat();
const myButton = document.querySelector("button");
myButton.onclick = myCat;
Reto cumplido!
HTML:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Random Dogs API</h1>
<p>How any dogs do you want?</p>
<input type="text" id="cajaTexto" name="nombre">
<button id = "boton">CLICK</button>
<div id="container">
</div>
<script src ="./main.js"></script>
</body>
</html>
CSS:
body{
background-color: cornflowerblue;
}
JS:
// ...
let boton = document.querySelector('#boton');
const container = document.getElementById('container');
const URL_BASE = 'https://dog.ceo/api/breeds/image/random/';
async function fetchData(numImages) {
try {
const response = await fetch(`${URL_BASE}${numImages}`);
const data = await response.json();
// Elimina el contenido anterior del contenedor, si lo hubiera
container.innerHTML = '';
for (let i = 0; i < numImages; i++) {
const img = document.createElement('img');
img.src = data.message[i];
img.height = 250;
img.style.padding = '10px';
img.style.borderRadius = '25px';
img.alt = 'Random dog photo';
container.appendChild(img);
}
} catch (error) {
console.error('Error:', error);
}
}
fetchData(4);
boton.addEventListener('click', function () {
const cajaTexto = document.getElementById('cajaTexto');
const numImages = parseInt(cajaTexto.value);
if (!isNaN(numImages) && numImages > 0) {
fetchData(numImages);
} else {
console.error('Invalid input. Please enter a valid number greater than 0.');
}
});
Interesante tema, no conocía nada
Modifiqué el reto anterior para que sea dinámico
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="estilos.css">
<title>GATOS ALEATORIOS</title>
</head>
<body>
<main>
<div class="container-main">
<h1>GATO MIAU MIAU</h1>
<label for="numGatos">¿Cuántos gatitos deseas?</label>
<input type="number" id="numGatos" placeholder="Escribe un número">
<div class="list-cat-img">
<img alt="cat-img">
</div>
<button>NEW CAT</button>
</div>
</main>
<script src="./main.js"></script>
</body>
</html>
*{
box-sizing: border-box;
}
body{
margin: 0;
padding: 0;
font-size: 62.5%;
background-image: url(https://e0.pxfuel.com/wallpapers/69/418/desktop-wallpaper-pin-de-trischell-magbuhat-en-cat-phone-fondos-de-gato-empapelado-de-gato-fondo-de-pantalla-de-dibujos-animados-cat-cartoon.jpg);
background-repeat: repeat;
}
main{
display: flex;
justify-content: center;
align-items: center;
}
.container-main{
width: 50%;
display: flex;
flex-direction: column;
align-items: center;
border: 1px solid black;
border-radius: 20px;
background-color: whitesmoke;
}
.container-main h1{
width:500px;
font-size: 3rem;
text-align: center;
}
.container-main label{
font-size: 1.5rem;
text-align: center;
}
.container-main input{
font-size: 1rem;
margin: 8px;
border-radius: 20px;
text-align: center;
}
.list-cat-img{
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 20px;
}
.list-cat-img img{
width:200px;
height: 200px;
}
.container-main button{
margin: 16px 0;
border: none;
background-color: aquamarine;
padding: 16px;
font-weight: bold;
font-size: 2rem;
border-radius: 50px;
}
const URL = "https://api.thecatapi.com/v1/images/search";
const input = document.querySelector("input");
const listImg = document.querySelector(".list-cat-img");
async function fetchData(url) {
const response = await fetch(url);
const data = await response.json();
const img = document.getElementsByTagName("img");
for (let j = 0; j < img.length; j++) {
img[j].src = data[j].url;
}
}
fetchData(URL);
const button = document.querySelector("button");
button.addEventListener("click",()=>{
fetchData(`${URL}/?limit=${input.value}`);
});
input.addEventListener("change",(e)=>{
listImg.innerHTML = "";
const queryParameter = `?limit=${e.target.value}`;
for (let i = 0; i < e.target.value; i++) {
const imgChild = document.createElement("img");
imgChild.setAttribute("alt","cat-img");
listImg.appendChild(imgChild);
}
fetchData(`${URL}/${queryParameter}`);
})
Endpoints y queryparameters
Son una de las formas en las que podemos modificar el resultado que nos va a dar nuestra API Rest, los endpoint son rutas que pueden ser diferentes para solicitar diferentes contenidos.
Los query parameters son informacion extra a los endpoints para poder limitar o expecificar el contenido pedido al API o backend. Por ejemplo, traeme las 5 razas de la 2da página /breeds?limit=5&page=2. Podemos decirle tambien con lso query parameters el formato en que queremos una imagen. Esto solo funciona si nuestra API esta preparada para recibir estos query parameters, por eso debemos fijarnos en la documentación.
const API_URL = 'https://api.thecatapi.com/v1/images/search?limit=3'; //Usamos query parameter ?limit=3 para que solo nos retorne 3 img
async function reload() {
const res= await fetch(API_URL);
const data = await res.json();
console.log(data)
const img1 = document.querySelector('img1');//creamos una constante para cada imagen
const img2 = document.querySelector('img2');
const img3 = document.querySelector('img3');
img1.src = data[0].url;//le decimos que traiga la imagen que esta en x posición(recuerda que empieza desde 0 no desde1)
img1.src = data[1].url;
img1.src = data[2].url;
};
reload();
Yo quisé intentar manipulando el Dom. Aquí les dejó mi código por si puede ayudar a alguien –
<h1>Soy un Gatito</h1>
<figure id="containerImag">
</figure>
<button onclick="reloadImag()" id="setCat">Otro gatito</button>
const ramdonImag = document.querySelector('#ramdonImag')
const containerImag = document.querySelector('#containerImag')
const API_URL = 'https://api.thecatapi.com/v1/images/search?limit=10'
const fetchData = async (url) => {
try {
const res = await fetch(url)
const data = await res.json()
data.forEach((item)=>{
const img = document.createElement("img");
img.src = item.url;
img.style='width:300px; height:300px'
containerImag.appendChild(img);
})
} catch (error) {
console.log(error)
}
}
function reloadImag(){
containerImag.innerHTML=''
fetchData(API_URL)
}
reloadImag()
Renderizando 4 fotos de perritos
.
Me encantan los cursos de JuanDC,
sería fenomenal si pudieras cerrar la barra lateral (o alargarla más) para poder acomodar el editor y seguir el curso a la par sin tapar el código
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?