I am struggling to fetch movies by its genres from API movies database. The error is always say that 'genres.map is not a function' or when I try to call selectedGenre to fetch the movie that associate with each genres by using document.GetElementById.value, it cannot read the .value thing. What I am doing wrong? Thank you ahead
const Discover = () => {
const navigate = useNavigate();
const [movies, setMovies] = useState([]);
const [genres, setGenres] = useState('');
const [searchTerm, setSearchTerm] = useState('');
const currentGenre = document.getElementById('genres').value;
const FEATURED_API = `https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=9a7243213d79e4344f8f16ce3b6098cf`;
const GENRES_API = 'https://api.themoviedb.org/3/genre/movie/list?api_key=9a7243213d79e4344f8f16ce3b6098cf';
const SEARCH_API = 'https://api.themoviedb.org/3/search/movie?api_key=9a7243213d79e4344f8f16ce3b6098cf&query='
useEffect(() => {
getMovies(FEATURED_API),
getGenres(GENRES_API)
}, []);
const getGenres = (API) => {
fetch(API)
.then(res => res.json())
.then((data) => {
setGenres(data.genres);
console.log(data.genres)
})
}
const getMovies = (API) => {
fetch(API)
.then((res) => res.json())
.then((data) => {
setMovies(data.results);
console.log(data.results);
});
};
const handleOnSubmit = (e) => {
e.preventDefault();
if(currentGenre) {
fetch(FEATURED_API `&with_genres=${currentGenre}`)
.then((res) => res.json())
.then((data) => {
setMovies(data.results)
console.log(data.results)
})
}
setGenres('')
// navigate(`/genre/movie/list/${genres.name}`)
}
const handleOnChange = (e) => {
// if(
// genres.id === movies.genres_ids
// )
setGenres(e.target.value)
}
// if(isFetching) return <Loader type='Loading films...'/>;
// if (error) return <Error />;
return (
<div className='flex flex-col'>.
<div className='w-full flex justify-between items-center sm:flex-row flex-col mt-4 mb-10'>.
<form onSubmit={handleOnSubmit}\>
<h2 className='font-bold text-3xl text-black text-left ml-4'>Discover</h2>
<select
value={currentGenre}
onChange={handleOnChange}
className='mt-4 ml-3'id='genres'\>
{genres.length > 0 &&genres.map((genre, i) => <option key={i} value={genres}>{genre.name}</option>)}
</select>
</form>
</div>
<div className='flex flex-wrap sm:justify-start justify-center gap-8'>
{movies.length > 0 &&
movies.map((movie) => <FilmCard key={movie.id} {...movie} />)}
</div>
</div>
)}
export default Discover
CodePudding user response:
I would start by structuring the data fetch differently, something more compact..
Like:
export const useData = (url) => {
const [state, setState] = useState();
useEffect(() => {
const dataFetch = async () => {
const data = await (await fetch(url)).json();
setState(data);
};
dataFetch();
}, [url]);
return { data: state };
};
Maybe error handling too, like:
function App() {
const [state, setState] = useState([])
const [hasError, setHasError] = useState(false)
const {loading, setLoading} = useState(false)
useEffect(() => {
setLoading(true)
fetch("/api/data").then(
res => {
setState(res.data);
setLoading(false)}
).catch(err => {
setHasError(true))
setLoading(false)})
}, [])
return (
<>
{
loading ? <div>Loading...</div> : hasError ? <div>Error occured.</div> : (state.map( d => <div>{d}</div>))
}
</>
)
}
I hope it helps you , Cheers!