Reputation: 465
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
Upvotes: 0
Views: 169
Reputation: 2376
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;
Upvotes: 1