I have created a react component that will display movie details after getting details from the TMDb API. The app working perfectly but there is one condition I am trying to handle i.e. when the movie is not found. In that, I case I want my background to be white instead of the movie poster. I want the same thing for title, overview, rating etc. I have used ternary operator for this.
However, my app still crashes this: -
Uncaught TypeError: Cannot read properties of undefined (reading 'backdrop_path')
at HeroArea
Here is my code: -
import React, { useState } from 'react'
import MovieDetailModal from '../MovieDetailsModal/MovieDetailModal';
import './HeroArea.css';
function HeroArea({ movie }) {
const [displayModal, setDisplayModal] = useState(false);
const displayMovieModal = () => setDisplayModal(true);
//Default background if movie.backdrop isn't found
const backdropImage = movie.backdrop_path !== null ?
{ backgroundImage: `url(https://image.tmdb.org/t/p/original/${movie.backdrop_path})` }
: {backgroundColor : "white"};
return (
<>
<MovieDetailModal status={displayModal} movie={movie} setStatus={setDisplayModal} />
<div className="hero-container" style={backdropImage} >
<div className="content-width info-container">
<div className="inner-container">
<h1>{movie.title ? movie.title : "No results found!"}</h1>
<p>{movie.overview ? movie.overview.substring(0, 250) : ""}...</p>
<button
onClick={displayMovieModal}
className="common-button view-more-button-hero">Display more</button>
</div>
</div>
</div>
</>
)
}
export default HeroArea
The short answer is, because movie is undefined, you can't access its properties.
You would need to make sure that movie is set before anything else for example:
const backdropImage = movie.backdrop_path !== null
? { backgroundImage:`url(https://image.tmdb.org/t/p/original/${movie.backdrop_path})` }
: {backgroundColor : "white"};
BECOMES
const backdropImage = movie && movie.backdrop_path !== null
? { backgroundImage:`url(https://image.tmdb.org/t/p/original/${movie.backdrop_path})` }
: {backgroundColor : "white"};
This also means you will need to make sure you only render this component if movie is set. for example:
return (
<>
<MovieDetailModal status={displayModal} movie={movie} setStatus={setDisplayModal} />
<div className="hero-container" style={backdropImage} >
<div className="content-width info-container">
<div className="inner-container">
<h1>{movie.title ? movie.title : "No results found!"}</h1>
<p>{movie.overview ? movie.overview.substring(0, 250) : ""}...</p>
<button
onClick={displayMovieModal}
className="common-button view-more-button-hero">Display more</button>
</div>
</div>
</div>
</>
)
BECOMES
if(movie){
return (
<>
<MovieDetailModal status={displayModal} movie={movie} setStatus={setDisplayModal} />
<div className="hero-container" style={backdropImage} >
<div className="content-width info-container">
<div className="inner-container">
<h1>{movie.title ? movie.title : "No results found!"}</h1>
<p>{movie.overview ? movie.overview.substring(0, 250) : ""}...</p>
<button
onClick={displayMovieModal}
className="common-button view-more-button-hero">Display more</button>
</div>
</div>
</div>
</>
)
}
return null;