killerprince182
killerprince182

Reputation: 465

My react app is crashing even after error handling. Why is this happening?

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

Answers (1)

Duenna
Duenna

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

Related Questions