Consume tu primera API REST

3/20
Recursos

Aportes 55

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad? Crea una cuenta o inicia sesión.

😄 Holaa! Esta es mi solución! Gracias a todos porque gracias a sus aportes resolví el reto!!

JS

const URL = 'https://api.thecatapi.com/v1/images/search';


async function myCat () {
    const res = await fetch(URL);
    const data = await res.json();
    const img = document.querySelector('img');
    img.src = data[0].url;
}

const myButton = document.querySelector("button");
myButton.onclick = myCat;

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 Cats with API REST</title>
</head>
<body>
    <header>
        <h1>Random Cats</h1>
    </header>
    <section class="container">
        <img alt="Cat random Picture" class="image">
        <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 .image {
    border-radius: 20px;
    margin: 20px;
    width: auto;
    height: 500px;
}
.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);
}

Pequeña solución con la API de Pokemon

Pokemon API

Repositorio

Listo los primeros retos!
Y como soy team dogs voy a completar este curso con esa APi

No es mucho pero es trabajo honesto.

Mi aporte al reto:

  • archivo .js : Le agregue que al cargar el DOM se ejecute la función, así ya nos muestra una imagen. Luego la función async, y luego obtengo en la constante reload el boton.
  • archivo .html : Con una flecha les indico que coloqué como id al boton “reload” que es lo que llamo en el archivo js
  • navegador : Hice un CSS muy básico para poner todo centrado y un poco de color al botón, quedando así en el navegador.

Aqui esta mi solucion al reto:D

<!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=Lato:[email protected];700&display=swap" rel="stylesheet">
    <title>Gatitos random</title>
</head>

<body>
    <main>
        <h1 class="title">Gatitos random</h1>
        <img class="img" alt="Foto de un gatito">
        <button class="button" id="anotherImg">Muestrame otra imagen</button>

        <script src="./main.js"></script>
    </main>
</body>

</html>
const URL = 'https://api.thecatapi.com/v1/images/search';
const button = document.getElementById('anotherImg');
const img = document.querySelector('img');

async function getCat() {
   const response = await fetch(URL);
   const data = await response.json();
   img.src = data[0].url;
}

button.onclick = getCat;
* {
   margin: 0;
   padding: 0;
   box-sizing: border-box;
   font-family: 'Lato', sans-serif;
}

main {
   display: flex;
   flex-direction: column;
   justify-content: center;
   align-items: center;
   gap: 20px;
   padding: 20px 0;
}

.img {
   width: 70%;
   height: 500px;
   object-fit: cover;
   border-radius: 10px;
   box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.4);
}

.button {
   padding: 10px 15px;
   border: none;
   border-radius: 5px;
   background-color: #f8cb2e;
   font-size: 17px;
   box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.1);
   cursor: pointer;
   transition: all 0.3s;
}

.button:hover {
   box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.3);
}

proyecto creado con vite con plantilla de typescript:

https://vitejs.dev/

A mi me gustan más los patitos así que elegí una API de patitos
Dejo la URL aquí por si quieren usarla (cors)
.
HTML

JavaScript

Mi aporte sin diseño ni nada y las cicatrices del aprendizaje 😅

En vez de usar un botón para recargar la pagina use un input
con estos atributos

<input type="button" value="Recargar" onclick="location.reload()">

y el js queda así

async function getURL () {
    const response = await fetch(URL);
    const data = await response.json();
    const img = document.querySelector('img');
    img.src = data[0].url;
}

getURL();

Asi quedó mi página con un poquito de CSS 😁

Js code

const img = document.querySelector('img');
const button = document.querySelector('button');
const URL = 'https://api.thecatapi.com/v1/images/search';

fetch(URL).then((response) => response.json()).then(data => {
  img.src = data[0].url;
})

button.onclick = async () => {
  const response = await fetch( URL );
  const data = await response.json();
  img.src = data[0].url;
}

Reto completado 😁

Código:

Este es mi aporte ❤️ , usé otra librería de gatitos

Deberían dar un curso sobre como trabajar con APIS y OAUTH… me lo has sacado de la punta de la lengua al tema porque justamente venía pensando que acceder a APIS publicas que no tienen validación es algo relativamente sencillo.

No obstante el mercado y los pedidos que hacen los clientes de determinadas implementaciones hay que usar OAUTH… ojala ese curso llegue pronto!

Saludos.

Voy a dejar otra vez, la API de Platzi ( creada por los mismos estudiantes).

Además, voy a dejar Hoppscotch ( Open Source ), para que puedan leer e hacer peticiones de sus API.

const functionDogs = async (id) => {
  const URL = `https://api.thedogapi.com/v1/images/search`;
  const res = await fetch(URL);
  const data = await res.json();
  const img = document.querySelector("img");
  img.src = data[0].url;
};

const button = document
  .querySelector("button")
  .addEventListener("click", () => {
    functionDogs();
  });```

Hola!! dejo mi solución del reto además si tienen problemas para entender los eventos les recomiendo el curso de manipulación del DOM es super bueno.

const URL = 'https://api.thecatapi.com/v1/images/search';

//**Peticion a la api con fetch
// fetch(URL)
//     .then(response => response.json())
//     .then(data => {
//         const img = document.querySelector('.img-cat');
//         img.src = data[0].url;
//         img.with = 400;
//         img.height = 400;
//     });

//**Peticion con Async Await
const getCat = async() => {
    try{
        const response = await fetch(URL);
        const data = await response.json();

        const img = document.querySelector('.img-cat');
        img.src = data[0].url;
        img.with = 400;
        img.height = 400;
    }catch(error){
        console.log(error)
    }
}

//**Accion para el evento
const reload = () =>{
    getCat();
}

//**Tomar el boton
const button = document.querySelector('.reload-cat');

//**Agregar evento
button.addEventListener('click', reload)

Así me quedo el reto

Codigo:

console.log('hola')
const URL ='https://api.thecatapi.com/v1/images/search';

const refresh = async() =>{
    const response = await fetch(URL);
    const data = await response.json();
    const img = document.getElementById('bannerImage');
    img.src = data[0].url;
}
const input = document.getElementById('buttoRefresh');
input.onclick = refresh;
refresh()

Team Dogs 🐶

const URL = 'https://api.thedogapi.com/v1/images/search'

const peticion = async () => {
  try {
    const img = document.querySelector('img')
    const res = await fetch(URL)
    const data = await res.json()
    img.src = data[0].url
  } catch (e) {
    console.error(e)
  }
}

const myButton = document.querySelector('button')

myButton.addEventListener('click', peticion)

Mi solución al reto:

const URL = 'https://api.thecatapi.com/v1/images/search';

const getMichi = async () => {
    const response = await fetch(URL);
    const data = await response.json();
    
    
    const img = document.querySelector('img')
    img.src = data[0].url;
}

getMichi();

const btn = document
    .getElementById('btn')
    .addEventListener('click', (evt) => {
        evt.preventDefault();
        getMichi();
    });

Asi resolvi el reto

Esta es mi solución al reto

<h1>Random Doggos</h1>
  <div>
    <img
      id="pic"
      alt="Random doggo photo">
  </div>
  <br>
  <button id="btn" >New Picture</button>
const URL = 'https://api.thedogapi.com/v1/images/search'

document.getElementById('btn').addEventListener('click', getRandomDoggoImage)

async function getRandomDoggoImage() {
  try {
    const res  = await fetch(URL)
    const data = await res.json()
    const img  = document.getElementById('pic')
    img.src    = data[0].url
  }
  catch(error) { console.error(error)}
}

Mi solución

  • HTML
<!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</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <h1>Gatitos aleatorios</h1>
    <img id="iden" alt="Foto de gatitos aleatorios">

    <button onclick="changeImg()">Otro gato</button>    

    <script src="main.js"></script>
</body>
</html>
  • JS
const URL = 'https://api.thecatapi.com/v1/images/search';
async function changeImg(){
    try{
        let res = await fetch(URL);
        let data = await res.json();
        const img = document.querySelector('#iden');
        img.src = data[0].url;
    }catch (e){
        console.error(e);
    }
    
}

result

console.log("estamos listos");

const url = "https://api.thedogapi.com/v1/images/search";

const getImage = async() => {
await fetch(url)
    .then(response => response.json())
    .then(data => {
        console.log(data);
        const img = document.querySelector('img')
        img.src = data[0].url
    });
};

    const refresh = document.querySelector('button');
    refresh.addEventListener('click', getImage);
    getImage();

este es mi aporte me indican que les parece, // h

<!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>Consumos de apis</title>
</head>

<body>
    <img alt="imagenes_gatos">
    <button class="button" id="refresh" onclick="refresh()">recargar</button>
    <script src="./index.js"></script>
</body>

</html>

js

const refresh = document.getElementById('refresh');
refresh.addEventListener("click", _ => {
    location.reload();
});

const API = ' https://api.thedogapi.com/v1/images/search';

fetch(API)
    .then(res => res.json())
    .then(data => {

        const img = document.querySelector('img')
        img.src = data[0].url;

    });

Mi Solución:

const API_CATS = 'https://api.thecatapi.com/v1/images/search';

// fetch(API_CATS)
//   .then(res => res.json())
//   .then(data => {
//     const img = document.querySelector('img');
//     img.src = data[0].url;
//   });

const getCats = async () => {
  const response = await fetch(API_CATS);
  const data = await response.json();
  const img = document.querySelector('img');
  img.src = data[0].url;
};

getCats();

const button = document.querySelector('button');
button.onclick = getCats;

Holaa, les dejo mi aporte 🐶
Link: Random Cats
Repo: Repositorio

Hola hola!
Les dejo por aquí mi reto
https://wfercanas.github.io/Kittenly/

solución al reto:
const URL = ‘https://api.thecatapi.com/v1/images/search’;

async function getLink() {
const respuesta = await fetch(URL)
const json = await respuesta.json()
const img = document.querySelector(“img”);
img.src = json[0].url;
}
getLink();

function getCat() {
location.reload();
}

Mi solución al reto

HTML

<body>
    <div class="container">
        <h1>Gatitos aleatorios</h1>
        
        <img class="img-cat" alt="Foto gatito aleatorio">
        <button onclick="cambiarGato()">Cambiar de gato</button>
    </div>

    <script src="./main.js"></script>
</body>

JS


const URL = 'https://api.thecatapi.com/v1/images/search';

async function cambiarGato() {
    const res = await fetch(URL);
    const data = await res.json();
    const img = document.querySelector('img');
    img.src = data[0].url;
}

Esta es mi solución a los retos aplicando algo de lo que aprendí en el curso de manipulación del DOM 😊

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">
    <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=Roboto&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="./src/styles.css">
    <title>Consumiendo mi primera API</title>
</head>
<body>
    <h1 class="title">Consumiendo mi primera API</h1>
    <button>Click me</button>
    <div id="img"> </div>
    <script src="./src/main.js"></script>
</body>
</html>

CSS

*{
    box-sizing: border-box;
    padding: 0;
    margin: 0;
}
html{
    font-size: 62.5%;
    font-family: 'Roboto', sans-serif;
}
body{
    background-color: rgb(164, 174, 115);
    font-size: 2rem;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-direction: column;
}
h1{
    margin-top: 20px;
}
button{
    margin: 25px 0 15px 0;
    background-color: rgba(255, 255, 255, 0);
    border: 1px solid black;
    border-radius: 10%;
    padding: 10px 8px;
    font-size: 1.5rem;
}
button:hover{
    cursor: pointer;
    background-color: rgb(137, 138, 101);
}
#img{
    background-color: rgba(56, 48, 21, 0.049);
    border-radius: 25px;
    width: 450px;
    height: 350px;
    background-size: cover;
}

Javascript

const URL = "https://api.thecatapi.com/v1/images/search";

async function getCat(){
    const res = await fetch(URL);
    const data = await res.json();
    const urlImg = data[0].url;
    const img = document.getElementById('img').style.backgroundImage = `url(${data[0].url})`;
}

const button = document.querySelector('button');
button.onclick = ()=>{
    getCat();
    console.log("Clickkkaksdkqas");
};

El código de ejemplo del profe. se vería de la siguiente manera en Typescript.

export interface Cat {
  breeds: any[];
  id:     string;
  url:    string;
  width:  number;
  height: number;
}
(async () => {
  console.log("Hello world.");
  const URL: string = "https://api.thecatapi.com/v1/images/search";
  const res: Response = await fetch(URL);
  const data: Cat[] = await res.json();
  const imgGotById: HTMLElement | null = document.getElementById("picture");
  

  if (imgGotById !== null) {
    const img: HTMLImageElement = imgGotById as HTMLImageElement; //para usar los
    //métodos de HTMLImageElement
    img.src = data[0].url;
  }
})();

Pero si quieres obtener la imagen con querySelector se vería así.

export interface Cat {
  breeds: any[];
  id:     string;
  url:    string;
  width:  number;
  height: number;
}
(async () => {
  console.log("Hello world.");
  const URL: string = "https://api.thecatapi.com/v1/images/search";
  const res: Response = await fetch(URL);
  const data: Cat[] = await res.json();

  const imgGotByQuery: HTMLImageElement | null = document.querySelector("img");

  if (imgGotByQuery !== null) {
    imgGotByQuery.src = data[0].url;
  }
})();

Reto de la clase, pero con Typescript

const URL: string = "https://api.thecatapi.com/v1/images/search";
const imgGotById: HTMLElement | null = document.getElementById("picture");
const button: HTMLElement | null = document.getElementById("boton");

async function updateImage () {
  const res: Response = await fetch(URL);
  const data: Cat[] = await res.json();
  const dataString: string = data[0].url;

  if (imgGotById !== null) {
    const img: HTMLImageElement = imgGotById as HTMLImageElement;

    img.src = dataString;
  }
};
updateImage();
if (button!== null) {
  button.onclick = updateImage;
}

HTML:

<body>
    <div id="app">
      <h1>Gatitos Random</h1>
      <img id="img-michi" alt="Michi all Random" />
      <button id="btn-reload" class="btn">Refresh</button>
      <!--  <div class="cargando">Reload image...</div> -->
    </div>
    <script type="module" src="/main.js"></script>
  </body>

CSS:

* {
  background-color: rgb(50, 60, 60);
  margin: 0;
  padding: 0;
  box-sizing: border-box;
  font-family: "Lato", sans-;
}
#app {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 20px;
  padding: 20px 0;
  color: white;
}

#app img {
  width: 70%;
  height: 500px;
  object-fit: cover;
  border-radius: 10px;
  box-shadow: 0px 3px 15px rgba(0, 0, 0, 0.4);
}

#app img:hover {
  cursor: pointer;
  transition: width 1s;
  transition: height 0.2s;
  width: 75%;
  height: 550px;
}

#app h1:hover {
  color: rgb(206, 205, 205);
  cursor: pointer;
}

.btn {
  padding: 10px 15px;
  border: none;
  border-radius: 5px;
  background-color: #0892e9;
  color: white;
  font-size: 17px;
  box-shadow: 0px 2px 0px rgba(0, 0, 0, 0.1);
  cursor: pointer;
  transition: all 0.3s;
}
.btn:hover {
  background-color: #0579c1;
  box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.3);
}

/* .cargando {
  display: none;
  position: absolute;
  width: 70%;
  height: 520px;
  background-color: black;
} */

JS:

import "./style.css";

const API_URL = "https://api.thecatapi.com/v1/images/search";
const btnClick = document.querySelector("#btn-reload");

const reload = async () => {
  const res = await fetch(API_URL);
  const data = await res.json();

  const img = document.querySelector("#img-michi");
  img.src = data[0].url;
};

setTimeout(() => {
  reload();
}, 1000);

btnClick.addEventListener("click", reload);

const URL = 'https://api.thecatapi.com/v1/images/search';

const getCat = async () => {
  const respose = await fetch(URL);
  const data = await respose.json()
  const img = document.querySelector('img');

  img.src = data[0].url;
}

const button = document.querySelector("button");
button.addEventListener("click", getCat);

asi me quedo n.n

Estructura HTML

<!DOCTYPE html>
<html lang="es">

<head>
    <meta charset="UTF-8">
    <meta name="Description" content="Extended Description">
    <meta name="robots" content="index,follow">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Consumo de APIs</title>
    <script defer src="./app.js"></script>

    <style>
        .random-cat-container,
        .random-cat-chal-container {
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
            margin-bottom: 48px;
        }
        img {
            background-repeat: no-repeat;
            background-position: center;
            background-size: cover;
        }
        .random-cat-img1,
        .random-cat-chal-img1 {
            width: 400px;
            height: auto;
        }
        input[type="button"] {
            margin: 16px 0;
        }
    </style>
</head>

<body>
    <div class="random-cat-container">
        <h1>Gatos aleatorios</h1>
        <img src="" alt="" id="random-cat" class="random-cat-img1">
    </div>
    <div class="random-cat-chal-container">
        <h1>Gatos aleatorios - Reto</h1>
        <img src="" alt="" id="random-cat-chal" class="random-cat-chal-img1">
        <input type="button" value="Recargar Imagen">
    </div>
</body>

</html>

Código JS

const URL = 'https://api.thecatapi.com/v1/images/search';

fetch(URL)
    .then(response => response.json())
    .then(data => { // obteniendo resultado de la primera promesa
        const img = document.querySelector('#random-cat');
        img.src = data[0].url;
        img.alt = 'Foto de Gatos';
    });

const getCatImage = async () => {
    try {
        const response = await fetch(URL);
        const data = await response.json();
        const img = document.querySelector('#random-cat-chal');
        img.src = data[0].url;
        img.alt = 'Foto de Gatos';
    } catch (error) {
        console.log(error.message);
    }
}

getCatImage();

const button1 = document.querySelector('.random-cat-chal-container input');

button1.addEventListener('click', () => {
    getCatImage();
})
//cargar ruta, cod de clase comentado
const url = "https://api.thedogapi.com/v1/images/search"

//voy a enviarle a mi función de fetch esa constante con el contenido de url


fetch(url)//nos devuelve una promesa
    .then(res =>res.json()) //conversión a objeto de js
    .then(data =>{
        const img = document.querySelector('img') 
        img.src= data[0].url //traemos la url de la imagen, la rendereizamos en el html
    }) //carga los datos, la api nos da unos datos con unas propiedades en json

//json viewer ext para chrome, para ver mejor el contenido de una api

Estaba esperando este curso, super bien y mejor si es con Juan

Aporte

const API = 'https://dog.ceo/api/breeds/image/random'

const fetch_api = async () => {

    const request = await fetch(API)
    const response = await request.json()
    const img = document.querySelector('img')
    img.src = response.message
}

window.addEventListener('DOMContentLoaded', fetch_api)

const button = document.querySelector('button')

button.addEventListener('click', fetch_api)

HTML

Js

Yo igual amo los Gatos 😄 , aunque ellos crean que nosotros somos sus esclavos

Usando asycn await

const url = 'https://api.thecatapi.com/v1/images/search';
const btn = document.querySelector('button');
const img = document.querySelector('img');
async function getImage(){
    const response = await fetch(url)
    const data = await response.json();
    const cat = data[0].url
    img.src = cat;
    return true
}

window.onload = getImage();
btn.addEventListener('click', getImage);

Mi solución:

const URL = "https://api.thecatapi.com/v1/images/search"

async function aleatorio() {
    const res = await fetch(URL)
    const data = await res.json()
    const img = document.querySelector('img')
    img.src = data[0].url
}

aleatorio(); //para que al cargar la página haya imagen.
const btnRandom = document.getElementById('aleatorio')
btnRandom.addEventListener('click', aleatorio)

Terminado el reto xd, me salió una imagen del HTTP status code 510

Hasta ahorita así va el mío! 😃
.

.
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:[email protected];300;400;700&display=swap"
      rel="stylesheet"
    />
  </head>
  <body>
    <h1>Perritos aleatorios</h1>
    <section class="card">
      <p class="card__title" id="title"></p>
      <img class="card__img" alt="Foto perrito aleatorio" />
      <div class="card__info">
        <p id="weight"></p>
        <p id="height"></p>
        <p id="lifeSpan"></p>
      </div>
    </section>
    <button id="button">¡Ver otro perro!</button>
    <script src="./main.js"></script>
  </body>
</html>

CSS

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  text-align: center;
  background-color: #13262f;
  font-family: 'Montserrat', sans-serif;
}

h1 {
  margin: 20px 0;
  color: #DB3A34;
  font-weight: 800;
  text-transform: uppercase;
}

.card {
  width: 550px;
  margin: 0 auto;
  background-color: #f2f2f2;
  box-shadow: 0 40px 60px -6px black;
  border-radius: 10px;
}

.card__title {
  font-size: 28px;
  background-color: #DB3A34;
  color: #fff;
  height: 60px;
  line-height: 60px;
  letter-spacing: 3px;
  border-radius: 10px 10px 0 0;
}

.card__img {
 width: 100%;
}

.card__info {
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
  height: 120px;
}

button {
  margin-top: 30px;
  width: 275px;
  height: 50px;
  border-radius: 20px;
  border: none;
  font-size: 20px;
  cursor: pointer;
  background-color: #DB3A34;
  opacity: 0.6;
  color: #fff;
  transition: 0.5s;
}

button:hover {
  opacity: 1;
}

JS

const URL = "https://api.thedogapi.com/v1/images/search";
const img = document.querySelector("img");
const title = document.getElementById("title");
const weight = document.getElementById("weight");
const height = document.getElementById("height");
const lifeSpan = document.getElementById("lifeSpan");
const button = document.getElementById("button");

// Con promesas
function getDogs() {
  fetch(URL)
    .then((res) => res.json())
    .then((data) => {
      img.src = data[0].url;
      if (data[0].breeds[0]) {
        title.innerText = data[0].breeds[0].name;
        weight.innerText = "Peso: " + data[0].breeds[0].weight.metric + " kg";
        height.innerText = "Altura: " + data[0].breeds[0].height.metric + " cm";
        lifeSpan.innerText =
          "Esperanza de vida: " + data[0].breeds[0].life_span;
      } else {
        title.innerText = "Sin información";
        weight.innerText = "Peso: Sin información";
        height.innerText = "Altura: Sin información";
        lifeSpan.innerText = "Esperanza de vida: Sin información";
      }
    });
}

// Con async/await
async function getDogs2() {
  const res = await fetch(URL);
  const data = await res.json();
  img.src = data[0].url;
  if (data[0].breeds[0]) {
    title.innerText = data[0].breeds[0].name;
    weight.innerText = "Peso: " + data[0].breeds[0].weight.metric + " kg";
    height.innerText = "Altura: " + data[0].breeds[0].height.metric + " cm";
    lifeSpan.innerText = "Esperanza de vida: " + data[0].breeds[0].life_span;
  } else {
    title.innerText = "Sin información";
    weight.innerText = "Peso: Sin información";
    height.innerText = "Altura: Sin información";
    lifeSpan.innerText = "Esperanza de vida: Sin información";
  }
}

button.onclick = getDogs2;

getDogs2();

Team Dogs por aquí ☝

Les dejo mi solución usando async await.
Combine dos APIs para que la respuesta de una este en la otra.
La api de imagen muchas veces devuelve el texto cortado ya que no lo separa en renglones si es muy largo el texto.

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="https://necolas.github.io/normalize.css/8.0.1/normalize.css">
    <title>Cats API REST</title>
</head>
<body>
    <img src="" alt="" id="cat-image">
    <p id="cat-fact"></p>  
    <button id="new-cat" onclick="getImage()">Get new</button>
    <script src="main.js"></script>
</body>
</html>

JS:

const img = document.getElementById("cat-image")
const text = document.getElementById("cat-fact")

const IMG_API = "https://cataas.com/cat/says/"
const FACT_API = "https://cat-fact.herokuapp.com/facts"
const NAME_API = ""


const randomize = arr => Math.floor(Math.random() * arr.length)

const getFact = async () => {
  const res = await fetch(FACT_API);
  const data = await res.json()
	const getOne = data[randomize(data)]
  return getOne.text
}

const getImage = async () => {
    const factText = await getFact()
    const res = await fetch(`${IMG_API}${factText}`)
    img.src = res.url;
    text.innerText = factText;
}
getImage()```

Para los curiosos 😅
OAuth u Open Authorization es un método de autenticación para que el usuario tenga la capacidad de delegar ciertas acciones para que sean hechas en su nombre.
Por ejemplo: Imagina que quieres que Platzi publique un tweet en tu cuenta de Twitter cada vez que apruebas un curso. En vez de dar tu usuario y contraseña a Platzi, a través de twitter puedes darle autorizar a Platzi a escribir tweet por ti en tu propia cuenta. Esto se puede realizar con OAuth 😃