I am creating a webapp where I can show a list of Pokemons on initial page load using PokéAPI. The list should show all the images of the Pokemons and its name, inside of an MUI Card, something like this: App UI example.
I am using two APIs. One for getting the list of all the Pokemon names and their details. Another for getting the specific Pokemon's image.
In order to create the UI, I am querying the first API to get the list of all the Pokemons. And then I am using the result of the first API in the second query to get the image of that Pokemon.
Here are both the components that I have created:
PokemonList.jsx
import Box from "@mui/material/Box";
import { useQueries, useQuery } from "@tanstack/react-query";
import axios from "axios";
import PokemonCard from "./PokemonCard";
const getPokemonList = async () => {
const { data } = await axios.get(
"https://pokeapi.co/api/v2/pokemon?limit=12&offset=0"
);
console.log(data);
return data;
};
const usePokemonList = () => {
return useQuery(["pokemonList"], () => getPokemonList());
};
const getPokemons = async (url) => {
const { data } = await axios.get(url);
return data;
};
const usePokemons = (pokemons) => {
return useQueries({
queries: pokemons?.results.map((pokemon) => {
return {
queryKey: ["pokemons", pokemon.name],
queryFn: getPokemons.bind(this, pokemon.url),
staleTime: Infinity,
enabled: !!pokemons.count,
};
}),
});
};
function PokemonList() {
const { data: pokemonList } = usePokemonList();
const { data: pokemons, isLoading } = usePokemons(pokemonList);
return (
<Box
sx={{
display: "flex",
justifyContent: "space-evenly",
flexFlow: "row wrap",
gap: "2em",
}}
>
{!isLoading &&
pokemons.map((pokemon) => (
<PokemonCard
key={pokemon.species.name}
name={pokemon.species.name}
image={pokemon.sprites.front_default}
/>
))}
</Box>
);
}
export default PokemonList;
PokemonCard.jsx
import { Card, CardContent, CardMedia, Typography } from "@mui/material";
import PropTypes from "prop-types";
PokemonCard.propTypes = {
image: PropTypes.string,
name: PropTypes.string,
};
function PokemonCard(props) {
return (
<Card sx={{ width: 225, flexWrap: "wrap" }}>
<CardMedia component="img" height="140" image={props.image} />
<CardContent>
<Typography variant="caption">{props.name}</Typography>
</CardContent>
</Card>
);
}
export default PokemonCard;
This is the error that I am getting, because the first API has not resolved yet. What should be the proper way to use useQueries here?
queries: pokemons?.results?.mapmake this change I think results is undefinedpokemonsis undefined here.