Como conectarse a una API (Async, Await, Fetch)
Tags: javascript, webdev, programming, beginners
Published: 2022-05-27 16:29:02

👋 El dia de hoy te enseñare como conectarte a una API utilziando, Async, Await y Fetch, para esto vamos a utilizar la api de [**PokeAPI**](https://pokeapi.co/) ya que es una API gratuita.

## Iniciando Proyecto
Primero te recomiendo crear un pequeño proyecto con **HTML** y **JavaScript** esto es para que podamos visualizar en el navegador las respuestas de la API.
`index.html`
```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>Conectar API</title>
</head>
<body>
  <h1>Como conectar una API</h1>
  <p>Veremos como conectar una API utilizando Async, Await y Fetch</p>

  <script src="main.js"></script>
  
</body>
</html>
```
`main.js`
```js
console.log('Hello World!')
```

## Conectando con la API
Ahora que tenemos los archivos listos, vamos a ir a [**PokeAPI**](https://pokeapi.co/) y copiar el siguiente enlace:
`https://pokeapi.co/api/v2/pokemon?limit=20&offset=0`

Crearemos una función en nuestro `main.js` llamada `llamandoApi` y la llamamos para que se ejecute.
```js
const llamandoApi = () => {
  console.log('Hello World')
}

llamandoApi()
```
Ahora utilizaremos fecth para llamar la API, y lo guardaremos en una constante llamada `response` pero como es asíncrono debemos utilizar `await`, siempre que utilicemos `await` en nuestra función debe ir `async` para que esto no nos genere un error, si no colocamos `await` a una promesa nos aparecerá algo como esto:
```
Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Object
```
Ahora haremos el llamado a la API:
```js
const llamandoAPI = async () => {
  const respuesta = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
  console.log(respuesta)
}

llamandoAPI()
```
Ahora si vas al navegador veras algo como esto:
```json
Response {type: 'cors', url: 'https://pokeapi.co/api/v2/pokemon?limit=20&offset=0', redirected: false, status: 200, ok: true, …}
```
Ahora para que nosotros podamos validar esta llamada por si tiene algún error utilizaremos `try catch`

```js
const llamandoAPI = async () => {
  try {
    const respuesta = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
    console.log(respuesta)
  } catch (error) {
    console.log(error);
  } 
}

llamandoAPI()
```
Esto nos permitirá validar la respuesta a la API, y esto hará que nuestra aplicación no se rompa.

## Accediendo a los datos
Ahora ya que tenemos la respuesta vamos a querer utilizar los datos, esto lo haremos utilizando el método de `.json()`, este nos permite acceder a la información json que nos devolvió la petición, este método de igual forma es asíncrono así que debe llevar la palabra `await` esto lo podemos guardar en una variable:
```js
const llamandoAPI = async () => {
  try {
    const respuesta = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
    
    const data =  respuesta.json()
    console.log(data)
    
  } catch (error) {
    console.log(error);
  } 
}

llamandoAPI()
```
Este objeto ya contiene todas las propiedades de los Pokemon:
![Datos](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ou5l5ule0usm7h2uvalg.png)
Ahora si queremos acceder a algún valor, lo podemos manipular como un objeto cualquiera, en este caso accederemos al nombre del primer valor:
```js
const llamandoAPI = async () => {
  try {
    const respuesta = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
    
    const data = await respuesta.json()

    console.log(data.results[0].name)
    
  } catch (error) {
    console.log(error);
  } 
}

llamandoAPI()
```
Y en nuestra consola del navegador debemos ver:
```
bulbasaur
```
Si puedes ver todo eso del data se ve muy largo, para eso podemos utilizar `destructuring` del objeto de la siguiente forma:
```js
const {results} = await respuesta.json()
console.log(results)
```
Y ahora solo veremos los Pokémon.
Si lo que quieres es ver todos los nombres de los Pokémon, podemos utilizar un `for` que nos muestro los nombres de cada Pokémon:
```js
const llamandoAPI = async () => {
  try {
    const respuesta = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
    
    const {results} = await respuesta.json()

    for (let i = 0; i < results.length; i++) {
      console.log(results[i].name)
    }
    
  } catch (error) {
    console.log(error);
  } 
}

llamandoAPI()
```
Esto lo podemos mejorar utilizando `.map()` también como vemos la respuesta nos devuelve 2 valores el de `name` y el de `url` así que podemos hacer destructuring de eso de la siguiente forma:

```js
const llamandoAPI = async () => {
  try {
    const respuesta = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
    
    const {results} = await respuesta.json()

    const pokemones = results.map(async (pokemon) => {
      const {name, url} = pokemon
      console.log(name, url)
    })
    
  } catch (error) {
    console.log(error);
  } 
}

llamandoAPI()
```
Y si lo estabas pensando estas en lo correcto, podemos hacer el llamado a cada uno de los Pokémon utilizando la url que nos pasa con `fetch()` de la siguiente forma:
```js
const llamandoAPI = async () => {
  try {
    const respuesta = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
    
    const {results} = await respuesta.json()

    const pokemones = results.map(async (pokemon) => {
      const {name, url} = pokemon
      const respuestaPokemon = await fetch(url)
      
    })
    
  } catch (error) {
    console.log(error);
  } 
}

llamandoAPI()
```
Y podemos aplicar lo antes visto, convertir la respuesta en un `.json()` y luego hacer destructuring de los datos que a nosotros nos interesa:
```js
const llamandoAPI = async () => {
  try {
    const respuesta = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
    
    const {results} = await respuesta.json()

    const pokemones = results.map(async (pokemon) => {
      const {name, url} = pokemon
      const respuestaPokemon = await fetch(url)
      const { types } = await respuestaPokemon.json()
      console.log(name, types[0].type.name)
    })
    
  } catch (error) {
    console.log(error);
  } 
}

llamandoAPI()
```
Si vemos esto en la consola del navegador, tendremos el nombre del Pokémon y su tipo:
```
bulbasaur grass
ivysaur grass
venusaur grass
charmander fire
charmeleon fire
charizard fire
wartortle water
blastoise water
squirtle water
caterpie bug
metapod bug
butterfree bug
weedle bug
kakuna bug
beedrill bug
pidgey normal
pidgeotto normal
pidgeot normal
rattata normal
raticate normal
```
Y de esta forma es como podemos hacer un llamado a alguna API.

## Status
Como vimos al inicio, si llamamos la respuesta sin convertirla a json nos daba algo como esto:
```
Response {type: 'cors', url: 'https://pokeapi.co/api/v2/pokemon?limit=20&offset=0', redirected: false, status: 200, ok: true, …}
```
Como puedes ver ahí tenemos una propiedad llamada `status`, el status se basa en los [**Códigos de estado de respuesta HTTP**](https://developer.mozilla.org/es/docs/Web/HTTP/Status), (_<u>te invito a que puedas profundizar mas este tema</u>_) esto nos da una pequeña lista:

- **Respuestas informativas** (100–199).
- **Respuestas satisfactorias** (200–299).
- **Redirecciones** (300–399).
- **Errores de los clientes** (400–499).
- **Errores de los servidores** (500–599).

Si te preguntas esto de que me sirve para el llamado de una API pues funciona de mucho ya que puedes revisar el estado y dependiendo de este hacer una u otra cosa.

En este caso podemos ver el status que nos de la API haciendo destructuring o podemos hacerlo por separado ya que podemos utilizar los datos para pasarlos a json:
```js
const data = await fetch('https://pokeapi.co/api/v2/pokemon?limit=20&offset=0')
console.log(data.status)
```
Si vemos en nuestra consola nos devulve:
```
200
```
Y viendo en en listado tenemos que:
- **Respuestas satisfactorias** (200–299).
Entonces podemos hacer una validación, para que siempre y cuando la conexión sea satisfactoria entonces haga lo que le pidamos, y si no que nos devuelva el error.
```js
const response = await fetch(
  'https://pokeapi.co/api/v2/pokemon?limit=20&offset=0'
)

if (response.status >= 200 && response.status < 300) {
  const data = await response.json()
  console.log(data)
}
```
 De esta forma nosotros validamos que la respuesta primero debe ser satisfactoria para nosotros poder utilizar los datos.

### Si quieres ver mas tutoriales como este puedes entrar a mi perfil y ahí encontraras una gran variedad de tips y tutoriales.👉[**Tips y Tutoriales.**](https://dev.to/rogerdimonte).