-1

I fetched the data like this:

  constructor(){
    super();    
    this.state = {
      fetchedData : [] 
    }
  }
  componentDidMount(){
    fetch("https://api.randomuser.me")
          .then(response => response.json())
          .then(data => {            
            this.setState({
                  fetchedData : data.results[0]
                          })
                              });                                                                                                                                     
  }

Got this result with this.state.fetchedData:

Complete Data fetched

Then tried the following code to destructure the result:

render(){    
let {name} = this.state.fetchedData;

It works fine and I got the following result with console.log(name):

Results with the First Level of destructuring

So I wanted to further move down the nested object, but when I tried the following code:

render(){    
    let {name:{first, last, title}} = this.state.fetchedData;

It gave me the following error:

Error message after deeper de-structuring

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
rebel
  • 3
  • 2
  • Your default value of `[]` doesn't make any sense - bear in mind that the component is likely going to be rendered at least once *before* the data arrives from the HTTP request. – jonrsharpe Jul 06 '20 at 09:14

1 Answers1

0

You have a mismatch of types here. You are initialising fetchedData with empty array, and then expect it to have properties first, last and tilte.

You should initialise with a valid entry instead of empty array:

constructor(){
    super();    
    this.state = {
      fetchedData : {name: {first: '', last: '', title: ''}}
    }
  }

Furthermore, this is needed because of the async request. The corresponding then handler (this.setState({fetchedData:...})) is invoked later. Therefore, your component will be rendered before the setState call with its initial values.

Benjamin Eckardt
  • 709
  • 6
  • 10
  • I am new to learning react, so this might take an explanation.**QUESTION1:** I am not sure that how can I define the structure of "fetchedData" in advance when I am not sure what would be the structure of the API output?? **QUESTION2:** I agree that there could be a type mismatch but then how it is working fine when "fetchedData.name" is executed, and error comes up when "fetchedData.name.title" is tried?? – rebel Jul 06 '20 at 10:39
  • **QUESTION1:** You should be sure of what the API is providing, otherwise you don't know what to access. It's simply not possible the write a client that is entirely agnostic. Only possibility would be some kind of meta model that describes the response of your api. But I assume that's not where this should go. **QUESTION2:** Sorry, forgot the `name` property. Added it to the answer. – Benjamin Eckardt Jul 06 '20 at 10:43
  • 1
    Thanks for this explanation. Although the problem was with the flow of execution as I was trying to use the data even before the API call was made. The initiation with empty array is working fine. However, your responses helped me to learn some things I appreciate your efforts. Hopefully, will catch up with you through another question. – rebel Jul 06 '20 at 11:20
  • @rebel since you unapproved the answer, please let me know in what way you would have expected an approvable answer to look like. – Benjamin Eckardt Oct 26 '20 at 15:47