Atousa Darabi
Atousa Darabi

Reputation: 927

Why can't read array child elements from json response in reactjs?

I get data json:

componentDidMount() {
        const {axios} = this.props
        const {invoice} = this.state

                axios({
                    method: 'get',
                    url: `/invoice`,
                }).then((result) => {
                    this.setState({invoice: result.data})
                }).catch((error) => {
                    this.setState({error: error.response.data[0]})
                })

    }

and my json data is like this:

{"branchId":"c3","id":"30","invoiceLines":[{"id":"089","productId":"7c"}],"sumTotalPrice":2700}

I try to show the "invoiceLines"'s id like this:

return(
<Grid container>
    <Grid item xs={12}>

{this.state.invoice.invoiceLines.map((item, i) => {
    <p key={i}>{item.id}</p>
})}

    </Grid>
</Grid>
)

but catch this error: TypeError: this.state.invoice.invoiceLines is undefined

Upvotes: 0

Views: 47

Answers (3)

xadm
xadm

Reputation: 8418

Loading data is async, render will be called without data at start. When data arrives setState will force view update - second render.

You need to prevent accessing not ready data - f.e. displaying 'loading'.

Example from docs

UPDATE: Defining initial state (constructor) only covers a real problem and is only helpful in simple cases - one/two levels deep. In the case of deeper structures, this is not practical.

Upvotes: 3

gqstav
gqstav

Reputation: 2082

As someone previously mentioned, loading data is async. Changing componentDidMount() to componentWillMount() might solve your issue?

Upvotes: 1

hiehuehue
hiehuehue

Reputation: 56

I believe you have not defined your initialState in the constructor, or it is like this.state = {invoice: []}

Try defining initial state as this.state = {invoice: {invoiceLines : []}} in the constructor

If this suggestion doesnot work post more information about the component

Upvotes: 1

Related Questions