Sprites reales con Promise.all en PokeAPI

Resumen

Reemplazar la imagen genérica de Ditto por el sprite real de cada Pokémon es el siguiente paso lógico cuando ya tienes la lista cargada desde PokeAPI. Aquí aprendes a encadenar peticiones, usar Promise.all y conectar los detalles con tu store de Redux para que cada tarjeta muestre su propia cara.

¿Cómo se estructura la respuesta de PokeAPI para obtener sprites?

La primera llamada a getPokemons devuelve una lista con el nombre de cada Pokémon y una URL individual. Esa URL es la puerta de entrada a los detalles completos.

Cuando entras a la URL de un Pokémon específico, el API responde con un objeto extenso que incluye habilidades, formas y, lo que nos interesa ahora, los sprites. Dentro de sprites viven las imágenes en distintas tomas, y la que vamos a usar es frontDefault.

¿Qué son los sprites en PokeAPI? Son las imágenes 2D de cada Pokémon en diferentes ángulos y estados. El campo frontDefault entrega la vista frontal estándar, ideal para tarjetas o listados.

¿Cómo preparar el entorno antes de pedir los detalles?

Antes de tocar la lógica nueva, conviene dejar el código limpio. En el video se hacen tres ajustes rápidos:

  • Devolver el offset original para trabajar con la primera generación.
  • Deshabilitar el middleware de Pokémon Eddy y dejar solo el logger.
  • Inicializar el servidor para confirmar que todo arranca sin errores.

Con esa base limpia, ya puedes concentrarte en obtener los detalles sin ruido de por medio.

¿Cómo usar Promise.all para pedir todos los detalles a la vez?

Después del primer fetch que trae la lista, necesitas una segunda ronda de peticiones: una por cada Pokémon. Hacerlas en serie sería lento, así que entra Promise.all.

Promise.all lanza un conjunto de promesas en paralelo y se resuelve solo cuando todas terminan. Si una falla, falla el bloque completo. Por eso es perfecto para este caso: o tienes todos los detalles, o sabes que algo salió mal.

Dentro de getPokemons, mapeas el resultado original y por cada Pokémon llamas a una nueva función, getPokemonDetails, pasándole el objeto. El await envuelve todo el Promise.all para esperar la resolución conjunta.

¿Por qué usar Promise.all en lugar de un for con await? Porque ejecuta todas las peticiones en paralelo en vez de una tras otra. Para 20 Pokémon, la diferencia entre paralelo y secuencial puede ser de varios segundos.

¿Dónde vive la función getPokemonDetails?

La función se escribe en el archivo api.js, junto al resto de las llamadas. Recibe el objeto Pokémon y devuelve una petición axios.get a la URL que ya viene en la respuesta inicial.

De la respuesta de Axios solo interesa la propiedad data, así que se retorna directamente. El manejo de errores se resuelve con un catch siguiendo el mismo patrón del resto del módulo.

Una vez creada, importas getPokemonDetails en app.js y haces el dispatch de la acción setPokemons, pero ahora pasando el array con los detalles completos en lugar de la lista mínima inicial.

¿Cómo conectar los sprites con el componente Pokémon Card?

Con los detalles ya en el store de Redux, toca propagarlos hacia los componentes visuales. Si abres Redux DevTools y revisas el árbol del estado, vas a ver que cada Pokémon ahora trae su objeto sprites con todas las variantes de imagen.

¿Qué cambios necesita el componente Pokémon Card?

El componente original solo recibía el nombre como prop. Ahora debe aceptar también la imagen:

  • Agregar image a los props que recibe.
  • Reemplazar la imagen hardcodeada de Ditto por la prop image.
  • Cambiar el alt para que use el nombre del Pokémon, no un texto fijo.

Este pequeño refactor convierte la tarjeta en un componente reutilizable y accesible, porque cada imagen tendrá su propia descripción semántica.

¿Cómo enviar la imagen desde Pokémon List?

En el componente padre, PokemonList, pasas la nueva prop al renderizar cada tarjeta. La ruta exacta dentro del objeto es pokemon.sprites.frontDefault.

Al guardar y volver al navegador, cada Pokémon aparece con su propia ilustración. Bulbasaur ya no se ve como Ditto, y la lista cobra identidad visual real.

¿Qué hago si frontDefault llega como null? Algunos Pokémon o formas alternativas no tienen sprite frontal por defecto. Conviene agregar un fallback, ya sea otra variante de sprite o una imagen placeholder, para evitar tarjetas rotas.

¿Cómo aplicar lo mismo con las habilidades de cada Pokémon?

El reto que queda abierto es replicar este flujo, pero con el array abilities que también viene en los detalles. La lógica es idéntica: ya tienes los datos en el estado, solo necesitas pasarlos como prop y renderizarlos en la tarjeta.

Piensa en cómo mostrarlas: ¿una lista debajo del nombre?, ¿badges al lado de la imagen?, ¿solo la habilidad principal? Comparte tu solución en la sección de aportes y cuéntanos qué decisión de diseño tomaste.