skip to Main Content

I’ve been trying for a while to display data from the Pokemon API in my browser, specifically the data for weight, height, name, and sprites.

Unfortunately, I keep getting an error when I try to map over it. Can someone tell me how to achieve this? What am I doing wrong? Can someone show me how to do it?"

This is my code:

import React from "react";
import { useGetPokemonByNameQuery } from "../Api/pokemonApi";

function PokemonCard() {
  const { data, error, isLoading, isError } = useGetPokemonByNameQuery();
  console.log(data)

  return (
    <>
      <ul>
        {isLoading && '...Loading...'}
        {isError && error.message}
        {data.map((pokemon) => (
          <li key={pokemon.id}>{pokemon.name}</li>
        ))}
      </ul>
    </>
  );
}
  
export default PokemonCard;
const pokemonApi = createApi({
  reducerPath: "pokemonApi",
  baseQuery: fetchBaseQuery({
    baseUrl: "https://pokeapi.co/api/v2/",
  }),
  endpoints: (builder) => ({
    getPokemonByName: builder.query({
      query: () => `/pokemon`,
    }),
  }),
});       
  
export const { useGetPokemonByNameQuery } = pokemonApi;
export default pokemonApi;
import { configureStore } from "@reduxjs/toolkit";
import { setupListeners } from "@reduxjs/toolkit/query";
import pokemonApi from '../Api/pokemonApi';

export const store = configureStore({
  reducer: {
    [pokemonApi.reducerPath]: pokemonApi.reducer
  },
  middleware: (getDefaultMiddleware) => {
    return getDefaultMiddleware().concat(pokemonApi.middleware);
  } 
});

setupListeners(store.dispatch);
import pokemonApi  from './Api/pokemonApi'
import { ApiProvider } from '@reduxjs/toolkit/query/react';
import PokemonCard from './Components/PokemonCard';

function App() {
  return (
    <ApiProvider api={pokemonApi}>
      <div className="App">
        <h1>Pokemon</h1>
        <PokemonCard /> 
      </div>
    </ApiProvider>
  );
}

export default App;

2

Answers


  1. You should first convert your data that is returned by react query to json object then u can map over it.

    data.json()
    

    data.map is not a function means your data is not converted to json object.

    Login or Signup to reply.
  2. Issues

    • The pokemon endpoint your are using doesn’t return an array, it returns an object with a results property that is an array.

      // 20231009084854
      // https://pokeapi.co/api/v2/pokemon
      
      {
        "count": 1292,
        "next": "https://pokeapi.co/api/v2/pokemon?offset=20&limit=20",
        "previous": null,
        "results": [
          {
            "name": "bulbasaur",
            "url": "https://pokeapi.co/api/v2/pokemon/1/"
          },
          {
            "name": "ivysaur",
            "url": "https://pokeapi.co/api/v2/pokemon/2/"
          },
          ...,
          {
            "name": "raticate",
            "url": "https://pokeapi.co/api/v2/pokemon/20/"
          }
        ]
      }
      
    • The RTKQ hooks return undefined data initially until data has been fetched and cached. The UI should account for this by using null-checks/guard-clauses on any data properties or by using the query status flags, e.g. isSuccess, isError, etc, to know when/if there is data to render.

    Solution

    Trivial solution is to use null-checks on the returned data property to access into it the results array, e.g. data?.results.map.

    function PokemonCard() {
      const { data, error, isLoading, isError } = useGetPokemonByNameQuery();
    
      return (
        <ul>
          {isLoading && "...Loading..."}
          {isError && error.message}
          {data?.results.map((pokemon) => (
            <li key={pokemon.name}>{pokemon.name}</li>
          ))}
        </ul>
      );
    }
    

    Another trivial solution would be to transform the response. You will still have the same issue with data being undefined until any data is fetched and cached.

    import { createApi, fetchBaseQuery } from "@reduxjs/toolkit/query/react";
    
    const pokemonApi = createApi({
      reducerPath: "pokemonApi",
      baseQuery: fetchBaseQuery({
        baseUrl: "https://pokeapi.co/api/v2/"
      }),
      endpoints: (builder) => ({
        getPokemonByName: builder.query({
          query: () => "/pokemon",
          transformResponse: (response) => response.results
        })
      })
    });
    
    export const { useGetPokemonByNameQuery } = pokemonApi;
    export default pokemonApi;
    
    function PokemonCard() {
      const {
        data,
        error,
        isLoading,
        isError,
        isSuccess
      } = useGetPokemonByNameQuery();
    
      return (
        <ul>
          {isLoading && "...Loading..."}
          {isError && error.message}
          {isSuccess &&
            data.map((pokemon) => <li key={pokemon.name}>{pokemon.name}</li>)}
        </ul>
      );
    }
    

    Demo

    Edit pokemon-api-with-rdx-query-and-react-cannot-read-properties-of-undefined

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search