Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Duplicated elements after mapping array pulled from API

I just tried to list all the pokemonsfrom 1 gen using Poke API but after getting the data using axios and mapping array i received duplicated items.
Do you have any idea how to fix it?
It’s my first project with API.

import React from "react";
import Card from "./Card";
import axios from "axios";

export default function Main() {
  const [allPokemons, setAllPokemons] = React.useState([]);

  React.useEffect(() => {
    axios.get("https://pokeapi.co/api/v2/pokemon?limit=151").then((res) => {
      const pokeUrls = res.data.results.map((pokemon) => pokemon.url);

      pokeUrls.map((url) =>
        axios.get(url).then((res) => {
          setAllPokemons((urls) => [...urls, res.data]);
        })
      );
    });

    
  }, [0]);

  console.log(allPokemons);

  const pokemonCard = allPokemons.map((pokemon) => (
    <Card
      name={pokemon.name}
      key={pokemon.id}
      id={pokemon.id}
      img={pokemon.sprites.front_default}
      type={pokemon.types[0].type.name}
    />
  ));

  return <div className="main-container">{pokemonCard}</div>;
}

i tried to change:

pokeUrls.map((url) =>
        axios.get(url).then((res) => {
          setAllPokemons((urls) => [...urls, res.data]);
        })
      );
    });

to:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

pokeUrls.map((url) =>
        axios.get(url).then((res) => {
          setAllPokemons(res.data);
        })
      );
    });

but unfortunately in this case i received the error: "Uncaught TypeError: allPokemons.map is not a function"

>Solution :

Three issues I see…

  1. Having [0] in your effect hook’s dependencies makes no sense. Just use [] to have it run once on mount
  2. The inner requests will resolve in the order of whatever responds fastest. This means the order of results from the first request won’t be the order you end up with in state.
  3. Because your effect hook only adds to the state data, you will end up with duplicates if it runs more than once. For example, this happens with <StrictMode>.

Try resolving all the data only once to maintain order and a clean state…

const getAllPokemon = async (limit = 151) => {
  const {
    data: { results },
  } = await axios.get("https://pokeapi.co/api/v2/pokemon", {
    params: { limit },
  });

  return Promise.all(
    results.map(async ({ url }) => (await axios.get(url)).data)
  );
};

and in your component

useEffect(() => {
  getAllPokemon().then(setAllPokemons).catch(console.error);
}, []);

I also suspect you’re seeing multiple log entries. This is because your state is updated every time a response is received which will result in multiple renders and thus, multiple console.log(allPokemons). Note that this does not mean you have duplicate data.

I strongly suggest never using console.log() for anything other than simple logging. Just use your data instead of worrying about what it looks like in the console.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading