1

I am learning React.js and trying to fetch API with fetch() and I tried to use componentDidMount() but I have a problem, you can see the pic at the end of the post.

import React, { Component } from 'react'


export default class App extends Component {
    
    state = {
      weather: []
    };
    
    
    fetchData() {
        fetch('prevision-meteo.ch/services/json/rochelle-17')
        .then((response) => response.json())
        .then((obj) => {
            console.log('javascript object: ', obj)
            this.setState({ weather: obj.results});
        })
        .catch((error) => {
            console.error(error)
          })
    }
    componentDidMount() {
        console.log('Le composant App est monté sur le DOM !')
        this.fetchData();
    }
    render() {
        return (
            <div>
                {this.state.weather&& this.state.weather.map((weatherRecord) => ( 
                  <div key={weatherRecord.city_info.name}>{weatherRecord.city_info.name}</div>
                 ))}
                Hello World !
                <button /*onClick={() => this.fetchData()}*/> Click me</button>
            </div>
        )
    }
}

I want to get the name of city_info in my page but didn't work!

This is the results in the console, can anyone help me? enter image description here

4
  • 1
    The error is telling you that obj.results is undefined. Your best bet is to use the debugger built into your browser to set a breakpoint on the this.setState() line and look at what obj is. Apparently it doesn't have a results property. Commented Oct 31, 2020 at 16:14
  • 1
    Side note: It's not the problem, but that code is susceptible to the fetch footgun I describe in this post on my anemic little blog. Commented Oct 31, 2020 at 16:15
  • 2
    Also consider using weather, not wheather, misspelled words are an easy source of frustrating bugs Commented Oct 31, 2020 at 16:16
  • but when i use console.log('javascript object: ', obj),i caan see the content of json in the console Commented Oct 31, 2020 at 16:24

2 Answers 2

1

Setting state is asynchronous so React is rendering before the state has been set. What you can do is put in a short circuit condition this.state.weather && to check if the weather array exists and only when it is available will the map operation be performed and you shouldn't get any errors.

import React, { Component } from 'react'


export default class App extends Component {
    
    state = {
      weather: []
    };
    
    
    fetchData() {
        fetch('http://localhost:3000/rochelle-17.json')
        .then((response) => response.json())
        .then((obj) => {
            //console.log('javascript object: ', obj)
            this.setState({ weather: obj.results});
        })
    }
    componentDidMount() {
        console.log('Le composant App est monté sur le DOM !')
        this.fetchData();
    }
    render() {
        return (
            <div>
                {this.state.weather&& this.state.weather.map((weatherRecord) => (
                    <div key={weatherRecord.city_info.name}></div>
                ))}
                Hello World !
                <button /*onClick={() => this.fetchData()}*/> Click me</button>
            </div>
        )
    }
}

Some Notes:

  • The newer versions of React support setting initial state like this, which is a bit cleaner:

     state = {
       weather: []
     }
    
  • It's also good practice to catch errors in case the API call fails. You can simply use .catch like this after the last .then():

     .catch((error) => {
       console.error(error)
     })
    
  • Since ES6 you don't need to use return for the <div> you are rendering. You can simply use map with curved brackets () instead of curly brackets {} to implicitly return

     {this.state.weather&& this.state.weather.map((weatherRecord) => ( 
       <div key={weatherRecord.city_info.name}></div>
     ))}
    
Sign up to request clarification or add additional context in comments.

1 Comment

thank u for ur help, the error was fixed but the problem now that's i can't get d name from json file!
0

Try this

export default class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      wheather: null
    };
  }

  fetchData() {
    fetch("http://localhost:3000/rochelle-17.json")
      .then((response) => {
        return response.json();
      })
      .then((obj) => {
        //console.log('javascript object: ', obj)
        this.setState({ wheather: obj });
      });
  }
  componentDidMount() {
    console.log("Le composant App est monté sur le DOM !");
    this.fetchData();
  }
 render() {
    return (
      <div>
        {this.state.wheather
          && <div key={this.state.wheather.city_info.name}>{this.state.wheather.city_info.name}</div>
        }
        Hello World !
        <button /*onClick={() => this.fetchData()}*/> Click me !</button>
      </div>
    )
  }
}

9 Comments

Thank u for ur help, the error was fixed but the problem now that's i can't get the name from json file!
That's a different issue then. Please check your 'obj.result' and structure of it. Or you can provide that JSON details here.
this is my JSON file : prevision-meteo.ch/services/json/rochelle-17 how can i get the infos frome this??
Is it whole 'obj.results'? 'obj.results' is an Array or Object?
i don't know but i want to get the name of ctiy from this file JSON : prevision-meteo.ch/services/json/rochelle-17 using fetch! the 'obj.results' i get it from a video
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.