Problem accessing Json API with React

Asked

Viewed 784 times

3

I am trying to access the following variable in the Json of an API:

page[0].infoBloco[0].tabela[0].dados[0].fonte.nome

I’m getting the bug:

TypeError: this.state.page[0] is undefined[Learn More] index.jsx:49

The Json the API returns is as follows:

[
    {
        "infoBloco": [
            {
                "tabela": [
                    {
                        "dados": [
                            {
                                "fonte": {
                                    "url": "http://www.google.com",
                                    "nome": "Site de buscas"
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    },
    {
        "infoBloco": [
            {
                "tabela": [
                    {
                        "dados": [
                            {
                                "fonte": {
                                    "url": "http://www.yahoo.com",
                                    "nome": "Outro site de buscas"
                                }
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

The code of the React page is as follows:

import React, { Component } from "react"

export default class extends Component {

  constructor(props) {
    super(props)
    this.state = { 
      page: [],
    }
  }

  componentDidMount() {
    this.getData()
  }

  getData = async () => {
    await fetch('http://localhost:3003/api')
      .then(resp => resp.json())
      .then(data => this.setState({ 
        ...this.state, 
        page: data,
      }))
  }

  render() {

    console.log(this.state.page[0].infoBloco[0].tabela[0].dados[0].fonte.nome)

    return (
      <div>
        Exemplo
      </div>
    )
  }
}

I can only access up to page[0], when I try to access any more internal element returns this same error. Would this error be caused by asynchronous access to the API? Can anyone help me fix this?

console.log(this.state.page) returns the full json Print

console.log(this.state.page[0]) returns the first json object Print

console.log(this.state.page[0].infoBloco) generates the error TypeError: this.state.page[0] is undefined[Learn More] index.jsx:49 Print

  • Just do console.log(page);, what result does it give? It should not be console.log(this.state.page);?

  • this.state.page returns the full json, from this.state.page[0].infoBloco is that the error appears TypeError: this.state.page[0] is undefined

2 answers

1


In React, to access objects/values that are in state of a component, you must use this.state, in your case would this.state.page

  • Actually I had forgotten to put this.state here in stackoverflow, but the original code is as console.log(this.state.page[0].infoBloco[0].table[0].data[0].fonte.name) and returns that same error. Thank you very much for the remark!

  • And if you do console.log(this.state.page);? Is the array empty? Or is it not even an array?

  • this.state.page returns a complete array with the two json objects. this.state.page[0] returns the first object of the array. this.state.page[0].infoBloco returns the error TypeError: this.state.page[0] is undefined

  • Add output to when you ask console.log(this.state.page), strange to give error only when you access a property of page[0]

  • Only to indicate what is recommended by the documentation is to use setState and not assign the state directly. This will evade certain specific cases that may give in particular bugs.

  • In the delete code, it has the call to setState, but the problem may be there. I’d like to see what the page to figure out. It may also be that you have not yet received the API response when you render, and are trying to access indexes in the array that do not yet exist, but ai this.state.page[0] should not return the object he is waiting for.

  • Okay, I added a link to the print right after console.log(this.state.page) in the original question

  • Apparently you are logging 2 times by the console output. This is then what I mentioned in the comment above, the first time you enter the render, the result of the API call has not yet returned.

  • And how can I make the result appear only after it is received from the api? I have to use some other code or middleware?

  • 1

    You can put an if no render, guy if (this.state.page.length === 0). You can change yours too .then who has the setState and make setState to put into state only what you need instead of the object root (pages). If you don’t need to use the specific path as you have in the example, where you use only 1 of the items, it is best to cycle to list everything, if they are empty nothing render, but when there is data, it will work normally.

  • 1

    It worked, I’m checking with if, showing a load message and when page is filled I rescan the component. Thank you very much!

Show 6 more comments

0

Solution supplied by Milk

import React, { Component } from "react"

export default class extends Component {

  constructor(props) {
    super(props)
    this.state = { 
      page: [],
    }
  }

  componentDidMount() {
    this.getData()
  }

  getData = async () => {
    await fetch('http://localhost:3003/api')
      .then(resp => resp.json())
      .then(data => this.setState({ 
        ...this.state, 
        page: data,
      }))
  }

  render() {

    //soluciona o problema do preenchimento da variável page
    if (this.state.page.length === 0) return <div>Loading, please wait…</div>

    return (
      <div> 
           Exemplo: {this.state.page[0].infoBloco[0].tabela[0].dados[0].fonte.nome}
      </div>
    )
  }
}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.