Home > database >  React: Uncaught TypeError: Cannot read properties of undefined (reading 'setState')
React: Uncaught TypeError: Cannot read properties of undefined (reading 'setState')

Time:08-27

I am new to learning React and I want to fetch something by making an API call which seems to not work for me. For the following code, I am getting an error in the console mentioned in the title.

The error is showing in the fetch statement for the below code and I am not been able to rectify it. What I am doing here is fetching the latitude and longitude of a position and passing it to a URL to fetch the weather.

import React, { Component } from "react"

class WeatherData extends Component{
  constructor(props){
    super(props);
    this.state ={
      weatherReport:[]
    };
  }

  componentDidMount() {
    navigator.geolocation.getCurrentPosition(function(position) {
      const lat =  position.coords.latitude;
      const lon = position.coords.longitude;
    fetch('https://api.openweathermap.org/data/2.5/weather?lat=' {lat} '&lon=' {lon} '&appid=xxxxxxxxxxxxxxxxxxxxxxx')
    .then(response => response.json())
    .then(data => this.setState({ weatherReport: data.main}));
    });
    
}
  render(){
    const  { weatherReport }  = this.state;

    
    return(
      <div>
          {weatherReport.temp}
      </div>
    );
  }
}

export default WeatherData;

Any help will be appreciated.

CodePudding user response:

You are using an anonymous function when getting the geolocation - this gives a new this to anything inside it, including the arrow function and its contents. Use an arrow function to maintain the correct scope when using callbacks.

Also, not sure why you are chaining an object in the url like that:

componentDidMount() {
    navigator.geolocation.getCurrentPosition((position) => { // this line
        const lat = position.coords.latitude;
        const lon = position.coords.longitude;
        fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=xxxxxxxxxxxxxxxxxxxxxxx`
          .then(response => response.json())
          .then(data => this.setState({
            weatherReport: data.main
          }));
        });
    }

CodePudding user response:

This is due to the difference between using the function keyword, and the "fat arrow" syntax (=>)

The function keyword created a new "this context" while the fat arrow inherits the parent context. In other words, when you use function, the value of the this keyword becomes something new inside of that function, whereas, with =>, it remains the same as it was outside of the function.

You can read more about the this keyword here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this

And more on the difference between function and => can be found here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions


So, instead of writing this:
getCurrentPosition(function(position) {

You should write this:
getCurrentPosition((position) => {

Full example:

import React, { Component } from "react"

class WeatherData extends Component {
  constructor(props) {
    super(props);
    this.state = {
      weatherReport: []
    };
  }

  componentDidMount() {
    navigator.geolocation.getCurrentPosition((position) => { // <- this is what has changed
      const lat = position.coords.latitude;
      const lon = position.coords.longitude;
      fetch('https://api.openweathermap.org/data/2.5/weather?lat='   { lat }   '&lon='   { lon }   '&appid=xxxxxxxxxxxxxxxxxxxxxxx')
        .then(response => response.json())
        .then(data => this.setState({ weatherReport: data.main }));
    });
  }

  render() {
    const { weatherReport } = this.state;

    return (
      <div>
        {weatherReport.temp}
      </div>
    );
  }
}

export default WeatherData;
  • Related