No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Endpoints y query parameters

4/20
Recursos

Aportes 81

Preguntas 9

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Les dejo un mini resumen de los endpoints y query parameters
Una buena RESTful API que cumple con todos los constrainst de REST deber铆a tener una clara documentaci贸n que especifique cada uno de los endpoints y query parameters disponibles para solicitar, editar, crear o eliminar recursos en el servidor
.

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();

鉁岎煆火煒

Cambie un poco la funcionalidad.

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.

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 鈥渆ndpoint鈥 (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 鈥渒ey=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

驴Qu茅 es un Endpoint de una API?


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聽&.

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()

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();

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

L贸gica de una loading en nuestra p谩gina 馃攦

Ingresamos nuestro loader antes de nuestra imagen en el archivo .html y le damos una clase 鈥榟ide鈥.

<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)

Problemas con la API al usar los Query Parameters

Hola comunidad buen dia!
Bueno a mi tambien me paso que al momento de colocar el 鈥榣imit=3鈥 cuando fui a la consola siempre me daba 10 objetos en el array. Esto pasa porque es necesario usar la API Key

Pero como consigo esta API Key y como la uso?

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);
    }
 })

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!

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 鈥渆lectronics鈥.

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 鈥渆lectronics鈥 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鈥檚:
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 鈥榙ata鈥 y por cada vuelta he hecho que genere una imagen con un atributo 鈥榮tyle鈥 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 鈥榠magenesContainer鈥. 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=鈥渨indow.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"/>
</body>
</html>
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 鈥淐onsulta鈥

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;
}

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;
Comparto mi c贸digo, agregue un forEach para evitar tener que cargar un ID por imagen asi se hace escalable si en el futuro hubiera que traer mas elementos. Tambien tiene un SetTimout para que se refresque sola la pagina cada 10 seg. en vez de tener que usar el boton `const`` ``API`` ``=`` 'https://api.thecatapi.com/v1/images/search?limit=3&page=2'` `const`` ``getNewMichi`` ``=`` ``async`` () ``=>`` { ` `聽 ``const`` res ``=`` ``await`` ``fetch``(``API``)` `聽 ``if`` (``!res.ok``) {聽 聽 ``throw`` ``new`` Error('La consulta fallo. STATUS: ' ``+ res.status``)聽 }` `聽 ``try`` {聽 聽 ``const`` data ``=`` ``await res.json``() 聽 聽 ``const`` img ``=`` document``.querySelectorAll``('img')` `聽 聽 img.forEach``((e,i) ``=>`` {``聽 聽 聽 聽 e.src`` ``= data``[i]``.url``聽 聽 聽 })` `聽 聽 ``setTimeout``(() ``=>`` {聽 聽 聽 ``getNewMichi``()聽 聽 }, 10000)聽 聽 聽 聽 } ``catch`` (err) {聽 聽 聽 console``.``error(err)聽 }}` `getNewMichi``()`
Se actualizo y ya no te permite poner de limite otras cosa que no sea una foto o 10 si pones mas de 1.

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

  • 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="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>

  • CSS
*{
    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;
}

  • JS
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