Invocando a la PokéAPI con RxJS en AngularDex

AngularDex (IV)

Rodrigo Bosarreyes
5 min readSep 5, 2023

¿Qué es la PokéAPI?

La PokéAPI es una interfaz de programación de aplicaciones (API, por sus siglas en inglés) que proporciona acceso a una gran cantidad de datos relacionados con Pokémon. Esta API es una fuente inagotable de información sobre estas criaturas, desde detalles sobre cada Pokémon en particular hasta información sobre movimientos, tipos, juegos y mucho más.

Para comenzar, te recomiendo visitar el sitio web oficial de la PokéAPI en https://pokeapi.co/ y explora su documentación para comprender cómo hacer solicitudes y acceder a los datos que necesitas para tus proyectos, aunque naturalmente en este post vamos a aprender su utilización básica.

Obtener listado de Pokémon

La PokéAPI nos brinda el endpoint “https://pokeapi.co/api/v2/pokemon” el cual puede recibir como parámetro un “offset” y “limit”. Estos parámetros son útiles para implementar paginación. Este endpoint nos devuelve objeto con información extra como el total de registros, el próximo y anterior endpoint, así como el propio listado de Pokémon.

Obtener listado de Pokémon

Como te puedes dar cuenta, este Endpoint solo nos devuelve el nombre y la URL de cada Pokémon, pero nosotros necesitamos conocer también sus tipos y su imagen, por lo que será necesario obtener su información más detallada.

Obtener detalle del Pokémon

De la misma manera que el anterior, la PokéAPI nos brinda el endpoint “https://pokeapi.co/api/v2/pokemon/{ID POKEMON]/”. En este caso nos devuelve toda la información del Pokémon, recordemos que los datos que nos interesa son el ID, nombre, imagen y tipos.

Obtener detalle Pokémon

Una vez definidas los endpoints podemos ponernos manos a la obra.

Vamos a nuestro PokemonService y lo adaptamos para tener la url del endpoint (con los parámetros offset y limit), también necesitaremos inyectar HttpClient y un método que invoque a la PokéAPI:

pokemon.service.ts

Ahora en nuestro app.component.ts implementamos la interfaz OnInit e inyectamos nuestro servicio, posteriormente en el ngOnInit lo invocamos, pero no vamos a settear nada, en su lugar simplemente vamos a ver qué nos devuelve la API:

app.component.ts

Y si nos fijamos en la consola del navegador vemos que el objeto que nos devuelve no se adapta a nuestra propiedad pokemons, la cual es un array de Pokemon, además, la información de “results” tampoco nos vale dado que no contiene todos los datos que necesitamos. Esta información faltante se encuentra en la url de cada elemento. Entonces ¿qué podríamos hacer?

Devtools

Aquí es donde entran en juego los operadores de RxJS. En primer lugar necesitamos transformar nuestro para quedarnos solamente con el array “results”.

pokemon.service.ts primera transformación

El operador tap es útil cuando queremos notificar o informar del estado de un Observable sin llegar a modificarlo, por ejemplo, en este caso lo utilizamos solamente para mostrar el objeto original por consola.

El operador mergeMap lo utilizamos para transformar un observable a uno nuevo que emitirá tantos eventos como elementos contenga, es decir, si nuestro observable original, en su propiedad results, contiene 10 pokémon, con este operador vamos a generar un observable que emitirá 10 eventos, uno por cada pokémon.

Si lo ejecutamos nuestra consola mostrará lo siguiente:

Devtools

Ahora necesitamos que por cada evento invoque a nuestro HttpClient con la URL del elemento, para ello volvemos a utilizar mergeMap:

pokemon.service.ts segunda transformación

Ahora nuestra consola nos muestra el detalle de cada uno de los pokémon:

Devtools

Perfecto, ahora nuestro servicio en primer lugar consulta los 10 primeros pokémon (o el número indicado en el offset), posteriormente por cada uno de ellos (de manera dinámica) obtiene la url que le corresponde y hace la petición GET correspondiente, devolviéndonos el detalle de cada Pokémon.

Solo nos quedaría un último paso que sería transformar este objeto que devuelve el detalle a una instancia de nuestra interfaz Pokémon. Para ello es tan simple como mappear en el subscribe de manera manual cada una de sus propiedades:

app.component.ts

Nota: en la propiedad types lo que hacemos es mappear el array del objeto del detalle para quedarnos solamente con el nombre, además, lo transformamos a TitleCase, de esta manera la propiedad types tendrá siempre un array de strings. Hacemos algo parecido para imageUrl, el cual navega entre propiedades anidadas hasta obtener la que nos interesa.

Importante: con esta nueva implementación, el array pokemons deja de estar “hardcodeado” y ahora pasa a ser inicialmente un array vacío. El código completo del app.component sería el siguiente:

app.component.ts

Y el resultado sería el siguiente:

Pokémon :)

¡Te reto que pruebes con un offset diferente y veas el resultado! También te propongo los siguientes desafíos: ¿puedes implementar que el límite de pokémon sea dinámico (parametrizable)? ¿podrías ordenar los Pokémon para se muestre del ID más bajo al más alto (puedes utilizar el operador toArray)? ¿podrías modificar el HTML para que las filas tengan el mismo número de columnas? ¡Cuéntame tus resultados!

Recuerda que tienes el código en el repositorio del proyecto.

--

--