albert_anthony6
albert_anthony6

Reputation: 614

React cannot read property 'length' of undefined but array is defined

I'm requesting data from an API within my react class component. Within my fetchData method, I setState to a key called data that initially is only an empty object. Withing the fetchData method, the object is filled with the data result from the API. I spread the result into the data object and within the object, I add a "directors" key that is an array that gets created because of the filter method. My issue is that I need the length of the directors array but this.state.data.directors.length caused an error saying that it's undefined. However, this.state.data.directors returns to me the array successfully and I can see within the console when I open the array up that the length property is the number that I actually need. Here is a version of my code.

constructor(){
        super();
        this.state={
            data: {},
        };
    }

    fetchData = async movieId => {

        try{
            const endpoint = `${API_URL}movie/${movieId}?api_key=${API_KEY}`;
            const result = await(await fetch(endpoint)).json();
            const creditsEndpoint = `${API_URL}movie/${movieId}/credits?api_key=${API_KEY}`;
            const creditsResult = await (await fetch(creditsEndpoint)).json();
            const directors = creditsResult.crew.filter(member => member.job === 'Director');

            this.setState({
                data: {
                    ...result,
                    actors: creditsResult.cast,
                    directors
                }
            }, () => {
                localStorage.setItem(`${movieId}`, JSON.stringify(this.state.data));
            });

        }catch(error){
            this.setState({error: true});
            alert(error);
        }
        this.setState({loading: false});
    }

    componentDidMount(){
        const {movieId} = this.props.match.params;

        if(localStorage.getItem(`${movieId}`)){
            console.log("grabbing from localStorage" + " " + movieId);
            this.setState({
                data: JSON.parse(localStorage.getItem(`${movieId}`))
            });
        } else {
            console.log("Grabbing from API");
            const {movieId} = this.props.match.params;
            this.setState({loading: true});
            this.fetchData(movieId);
        }
    }

    render(){
        const {data} = this.state;
        console.log(this.state.data.directors.length);
        return(

I expected to get the length property from the directors array since console.logging the directors array return an array with an object in it.

Upvotes: 0

Views: 1944

Answers (1)

Jackson
Jackson

Reputation: 3518

You are not defining the initial state of the directors array. As a result of this, directors is undefined until after the API request has been resolved

this.state = {
  data: {
    directors: []
  }
}

Upvotes: 2

Related Questions