Asif Biswas
Asif Biswas

Reputation: 171

TypeError: undefined is not an object (evaluating 'object['body']')

i got an array from server. here is the array:

[{"body":"one"},{"body":"two"},{"body":"three"}]

in Home2 component:

import React, { Component } from 'react';

class Home2 extends Component {
    constructor() {
        super()
        this.state={
            status:''
        }
    }
    componentDidMount(){
        let store = JSON.parse(localStorage.getItem('login'))
        var url = 'http://127.0.0.1:8000/myapi/allpost/?format=json'
        fetch(url,{
            method:'GET',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Token '+store.token
            }
        })
        .then(res=>res.json().then(result=>{
            this.setState({status: result})
        }))
    }
    render() {
        var list = this.state.status
        var object = list[0]
        console.log(object['body'])// <-- what is the problem?
        return (
            <div>
                <h1>Hello</h1>
            </div>
        );
    }
}

export default Home2;

when the code run, it shows TypeError: undefined is not an object (evaluating 'object['body']')

where is the problem? how to console.log 'one' ?

Upvotes: 1

Views: 3385

Answers (2)

Turtlean
Turtlean

Reputation: 579

As people pointed out in the comments, an initial render is done before componentDidMount, so that's the reason why you're getting the error

To overcome that, you could return some default value (i.e Loading... div) in case this.state.status has not received the response yet:

render() {
    var list = this.state.status
    var object = list[0]
    if (!object) {
      return (
        <div>
          Loading...
        </div>
      )
    }
    console.log(object['body'])// <-- what is the problem?
    return (
        <div>
            <h1>Hello</h1>
        </div>
    );
}

I also found this interesting answer explaining more about the initial render and React's lifecycle: https://stackoverflow.com/a/45343644/5745962

Upvotes: 3

Ran Marciano
Ran Marciano

Reputation: 1531

Your render method is called before componentDidMount method. Therefore you need to check if your object exists before you try to access a property of his.

also, you need to decide what kind of value you want to set in the status (it's a string or an array? from your code it seems like it should be an array of objects )

try to do it like this:

import React, { Component } from 'react';

class Home2 extends Component {
    constructor() {
        super()
        this.state={
            status:[]
        }
    }
    componentDidMount(){
        let store = JSON.parse(localStorage.getItem('login'))
        var url = 'http://127.0.0.1:8000/myapi/allpost/?format=json'
        fetch(url,{
            method:'GET',
            headers: {
                'Content-Type': 'application/json',
                'Authorization': 'Token '+store.token
            }
        })
        .then(res=>res.json().then(result=>{
            this.setState({status: result})
        }))
    }
    render() {
        if(this.state.status.length){
        var list = this.state.status
        var object = list[0]
        console.log(object['body'])// <-- what is the problem?
        return (
            <div>
                <h1>Hello</h1>
            </div>
        );
        }
        else {
          return null; //or return in here some kind of loader
        }
    }
}

export default Home2;

Upvotes: 1

Related Questions