I have a problem, that I can’t figure out. After fetching data to an array I can display this array, but I can’t display just one object in it or map through it
useMemo(() => {
// setTabIsLoading(true);
console.log(tabIsLoading);
const contentArray: Array<anime> = [];
fetchingArray.map((animeId: string) => {
const animeListHandler = async () => {
try {
const response = await fetch(
`https://api.jikan.moe/v4/anime/${animeId}`
);
if (response.ok) {
const data = await response.json();
const transformedData = {
id: data.data.mal_id,
name: data.data.title,
image: data.data.images.jpg.large_image_url,
description: data.data.synopsis,
score: data.data.score,
};
contentArray.push(transformedData);
}
} catch (err) {
console.error(err);
}
};
animeListHandler();
});
if (contentArray) {
console.log(contentArray);
console.log(contentArray[1]);
const content = [];
contentArray.map((anime) => {
console.log(`anime: ${anime}`);
content.push(<AnimePagesBox anime={anime} key={anime.id} />);
return;
});
console.log(content);
setActivePageContent(content);
setTabIsLoading(false);
}
}, [activePage, tabIsLoading]);
that’s the output of the code (in cases of logging contentArray
it shows full array with object):
true
Account.tsx:70 []
Account.tsx:71 undefined
Account.tsx:78 []
Account.tsx:41 false
Account.tsx:70 []
Account.tsx:71 undefined
Account.tsx:78 []
I also tried to add this array to an array in useState
. Sometimes it worked, but still was an issue, that after getting to this page back I didn’t see the output. So I don’t even know, what to do
If I create a guard, that mapping starts only, when the length of the array is greater than 0, so it doesn’t start
2
Answers
It seems like you are facing an issue where you can’t display individual objects from the contentArray.
The fetch function is asynchronous, and you are making multiple asynchronous requests inside the fetchingArray.map loop.
You can use
Promise.all
to wait for all requests to complete before processing the contentArray.As others have suggested, use
Promise.all
. It will return a promise containing the results of every promise passed into it. Also, you should not pass the entireanime
object into the subcomponent. Try to pass primitive values if you can. If you look at the<AnimeBox>
component below, you will see how props can be spread into the component.Here is a runnable Stack Snippet demonstrating this:
Note: I switch from
async
/await
toPromise.then
in the snippet below, because the snippet’s Babel version does not support the former.