I am trying to store data from the TMDB movie api using a custom react hook .
useFetch.js
JavaScript
x
41
41
1
import {React,useState,useEffect} from 'react';
2
3
4
export default function useFetch() {
5
6
const key = process.env.REACT_APP_API_KEY;
7
8
//the urls I want to get data from
9
const specificTypes = [
10
{'Type':'Top Rated', 'url' :`https://api.themoviedb.org/3/movie/top_rated?api_key=${key}`},
11
{'Type':'Trending', 'url' :`https://api.themoviedb.org/3/trending/movie/day?api_key=${key}`},
12
];
13
14
15
16
const [movieTypes,setMovieTypes] = useState([]); //this is where I want to store url data
17
18
useEffect(()=>{
19
20
const fetchSpecificTypes = async ()=>{
21
22
const promises = [];
23
specificTypes.map(async type=>{
24
let response = await fetch(type.url);
25
let res = await response.json();
26
promises.push(res.results);
27
});
28
console.log({promises}); data is stored in promises successfully
29
setMovieTypes(promises); //how I try to set the movies
30
31
32
}
33
34
fetchSpecificTypes();
35
36
},[]);
37
38
return {movieTypes};
39
40
}
41
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
JavaScript
1
35
35
1
import {React , useState,useEffect} from 'react'
2
import useFetch from './useFetch';
3
import '../App.css';
4
5
export default function MovieList() {
6
7
const {movieTypes} = useFetch();
8
const baseImgUrl = "https://image.tmdb.org/t/p";
9
const size = "/w400";
10
11
12
return (
13
<div className="movie-list">
14
{
15
movieTypes.map(movie=>{
16
return (
17
<>
18
{
19
Object.values(movie).map((val,k)=>{
20
let path = baseImgUrl + size + val.backdrop_path; //full image path
21
return <div className= "movie-item" key = {val.id}>
22
<img alt = "movie" src = {path}/>
23
<h4 className="movie-overview"> {val.overview} </h4>
24
<p className="movie-title">{val.title}</p>
25
</div>
26
})
27
}
28
</>
29
)
30
})
31
}
32
</div>
33
);
34
}
35
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()
JavaScript
1
10
10
1
const fetchSpecificTypes = async() => {
2
const promises = [];
3
for(let i=0; i<specificTypes.length; i++) {
4
let response = await fetch(specificTypes[i].url);
5
let res = await response.json();
6
promises.push(res.results);
7
}
8
setMovies(promises);
9
}
10
JavaScript
1
7
1
const fetchSpecificTypes = async() => {
2
const results = await Promise.all(specificTypes.map(type => fetch(type.url)));
3
const results2 = await Promise.all(results.map(res => res.json());
4
const movies = results2.map(res => res.results);
5
setMovies(movies);
6
}
7