ReactFix
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • React
  • React Native
  • Programming
  • Object Oriented Programming

Thursday, November 17, 2022

[FIXED] How to query data using 'useQueries' when it is dependent on previous query?

 November 17, 2022     react-query, reactjs   

Issue

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?


Solution

The error is telling you that the thing you're trying to map for your useQueries call is null or undefined. Which makes sense if the previous result has not yet returned. Additionally your hooks are a little too brittle in how their integrated. I would suggest refactoring your usePokemons hook to just take a list of pokemons (not an object with results) and default it to being empty. e.g.

const usePokemons = (pokemons) => {
  pokemons = pokemons || [];
  return useQueries({
    queries: pokemons.map((pokemon) => {
      return {
        queryKey: ["pokemons", pokemon.name],
        queryFn: getPokemons.bind(this, pokemon.url),
        staleTime: Infinity,
      };
    }),
  });
};

Then you just change how you integrate the two:

function PokemonList() {
  const { data: pokemonList, isLoading: isListLoading } = usePokemonList();
  const { data: pokemons, isLoading: isImagesLoading } = usePokemons(pokemonList?.results);
// ... etc


Answered By - Chad S.
Answer Checked By - - Clifford M. (ReactFix Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Google+
  •  Stumble
  •  Digg
Newer Post Older Post Home

Featured Post

Is Learning React Difficult?

React is difficult to learn, no ifs and buts. React isn't inherently difficult to learn. It's a framework that's different from ...

Total Pageviews

Copyright © ReactFix