Reputation: 606
I successfully fetch data of a movie inside useEffect()
. However, when the page is reloaded, previously fetched data disappears and 404 errors are printed out in the console. How could it be prevented?
This is the component that is reloaded:
import {useState, useEffect, useContext} from "react";
import Topbar from '../Header/Topbar';
import { fetchSelectedMovie } from "../../services/movies.service";
import {Grid, Card, CardMedia} from '@material-ui/core';
import noImage from '../../images/no-image-available.png';
import { MoviesContext } from "../../services/context";
import './Pages.css';
const posterBaseUrl = "https://image.tmdb.org/t/p/w300";
interface Genre {
id: number;
name: string;
}
interface Movie {
id: number;
title: string;
vote_average: number;
overview: string;
poster_path?: string;
release_date: string;
budget: number;
revenue: number;
genres: Genre[];
}
const MoviePage = (props: any) => {
const { selectedMovie } = useContext(MoviesContext);
const [movie, setMovie] = useState<Movie>(
{
id: 0,
title: '',
vote_average: 0,
overview: '',
poster_path: noImage,
release_date: '',
budget: 0,
revenue: 0,
genres: [],
}
);
const [movieImg, setMovieImg] = useState<string>(noImage);
useEffect(() => {
const callAPI = async () => {
const fetchedMovieInfo = await fetchSelectedMovie(Number(selectedMovie));
setMovie(fetchedMovieInfo);
setMovieImg(posterBaseUrl+fetchedMovieInfo.poster_path);
}
callAPI();
}, [selectedMovie]);
return (
<>
<Topbar></Topbar>
<Grid container spacing={2} className="container-movie-page">
<Grid item xs={6} sm={3}>
<Card className="card">
<CardMedia
component="img"
alt={"Poster of " + movie.title}
image={movieImg}
title={movie.title}
/>
</Card>
</Grid>
<Grid item xs={6} sm={9} className="align-left">
<h1 className="title">
{movie.title}
</h1>
</Grid>
</>
);
}
export default MoviePage;
Movie id selectedMovie
is got from App.tsx
component using React Context, it's default value = 0: const [selectedMovie, setSelectedMovie] = useState(0);
This is the call to the API to fetch data:
export async function fetchSelectedMovie (currentMovieId: number ) {
return await fetch(
`${movieApiBaseUrl}/movie/${currentMovieId}?api_key=${process.env.REACT_APP_API_KEY}`
)
.then((res) => res.json())
.then((body) => {return body})
.catch(() => {
return {};
});
}
React Context that is used:
import React from "react";
import { Movie } from "./movies.service";
export const MoviesContext = React.createContext<{
movies: Movie[];
updateMovies: Function;
selectedMovie: number;
setSelectedMovie: (value: number) => void;
}>({
movies: [],
updateMovies: Function,
selectedMovie: 0,
setSelectedMovie: () => {},
});
These are 404 errors I receive:
Upvotes: 1
Views: 62
Reputation: 26
Is the selectedMovie
present in the MoviePage component after you reload the page? It might not be present and you pass an undefined value to the API thus the 404 error.
A good idea would be to render the MoviePage only when the selectedMovie exists or add a check in the useEffect to call the API only if the selectedMovie is defined.
Could you also add the Context and API call code so we can see what it does? Looking at your screenshot it looks like you might be passing an ID equal to 0 to the API and a movie with such ID might not exist hence the 404 error.
Edit: Then it's probably just a matter of the API not being able to find a movie with an ID of 0. In this case, a 404 error is an indicator that the server just couldn't find what you were searching for. You can read more about error codes here.
In order to handle such errors you can look up the error code in the response and handle it as desired:
fetch('/movies/${movieID}').then(function(response) {
if (response.status === 404) {
console.log("Server couldn't find such movie!");
}
})
Upvotes: 1