I am trying to store data from the TMDB movie api using a custom react hook .
useFetch.js
import {React,useState,useEffect} from 'react';
export default function useFetch() {
const key = process.env.REACT_APP_API_KEY;
//the urls I want to get data from
const specificTypes = [
{'Type':'Top Rated', 'url' :`https://api.themoviedb.org/3/movie/top_rated?api_key=${key}`},
{'Type':'Trending', 'url' :`https://api.themoviedb.org/3/trending/movie/day?api_key=${key}`},
];
const [movieTypes,setMovieTypes] = useState([]); //this is where I want to store url data
useEffect(()=>{
const fetchSpecificTypes = async ()=>{
const promises = [];
specificTypes.map(async type=>{
let response = await fetch(type.url);
let res = await response.json();
promises.push(res.results);
});
console.log({promises}); data is stored in promises successfully
setMovieTypes(promises); //how I try to set the movies
}
fetchSpecificTypes();
},[]);
return {movieTypes};
}
When I console.log({promises}) I get this object where the 2 items are the movie types with 20 movies inside :
And then when I try to display the movies from the object above in another component :
MovieList.js
import {React , useState,useEffect} from 'react'
import useFetch from './useFetch';
import '../App.css';
export default function MovieList() {
const {movieTypes} = useFetch();
const baseImgUrl = "https://image.tmdb.org/t/p";
const size = "/w400";
return (
<div className="movie-list">
{
movieTypes.map(movie=>{
return (
<>
{
Object.values(movie).map((val,k)=>{
let path = baseImgUrl + size + val.backdrop_path; //full image path
return <div className= "movie-item" key = {val.id}>
<img alt = "movie" src = {path}/>
<h4 className="movie-overview"> {val.overview} </h4>
<p className="movie-title">{val.title}</p>
</div>
})
}
</>
)
})
}
</div>
);
}
I get nothing no movies displayed . I would appreciate your help with this .
Advertisement
Answer
Await is not working as expected inside Array.map().
You should either use for loop or use Promise.all()
const fetchSpecificTypes = async() => {
const promises = [];
for(let i=0; i<specificTypes.length; i++) {
let response = await fetch(specificTypes[i].url);
let res = await response.json();
promises.push(res.results);
}
setMovies(promises);
}
const fetchSpecificTypes = async() => {
const results = await Promise.all(specificTypes.map(type => fetch(type.url)));
const results2 = await Promise.all(results.map(res => res.json());
const movies = results2.map(res => res.results);
setMovies(movies);
}