React-Native Weather API failed fetch request

Hi,

I am having an issue with my React-Native weather application and fetching weather data from openweathermap.org.

I have two react hooks in my application:

  • The first hook gets the coordinates of the device’s current position (useGeolocation).
  • The second hook makes a fetch request to OpenWeatherMap for the current weather data (useFetch).

My useGeolocation hook works fine and retrieves the current position and returns a latitude and longitude. I then use these coordinates in my API request when calling my useFetch hook so that I have an accurate location when retrieving the weather.

The problem lies within my useFetch hook. I am passing a url parameter to my hook and using an async/wait arrow function within a useEffect hook to fetch the data from the API.

However, once the hook has been called and the fetch request is made. The response returns the following:
LOG weather data {“cod”: “400”, “message”: “wrong latitude”}
LOG weather data {“cod”: “400”, “message”: “wrong longitude”}
Then a third response returns a portion of the data with the following :

Actual response
  "base": "stations",
  "main": {
    "temp": 282.55,
    "feels_like": 281.86,
    "temp_min": 280.37,
    "temp_max": 284.26,
    "pressure": 1023,
    "humidity": 100
  },
  "visibility": 16093,
  "wind": {
    "speed": 1.5,
    "deg": 350
  },
  "clouds": {
    "all": 1
  },
  "dt": 1560350645,
  "sys": {
    "type": 1,
    "id": 5122,
    "message": 0.0139,
    "country": "US",
    "sunrise": 1560343627,
    "sunset": 1560396563
  },
  "timezone": -25200,
  "id": 420006353,
  "name": "Mountain View",
  "cod": 200
  }

Instead of the following:

Expected response
{
  "coord": {
    "lon": -122.08,
    "lat": 37.39
  },
  "weather": [
    {
      "id": 800,
      "main": "Clear",
      "description": "clear sky",
      "icon": "01d"
    }
  ],
  "base": "stations",
  "main": {
    "temp": 282.55,
    "feels_like": 281.86,
    "temp_min": 280.37,
    "temp_max": 284.26,
    "pressure": 1023,
    "humidity": 100
  },
  "visibility": 16093,
  "wind": {
    "speed": 1.5,
    "deg": 350
  },
  "clouds": {
    "all": 1
  },
  "dt": 1560350645,
  "sys": {
    "type": 1,
    "id": 5122,
    "message": 0.0139,
    "country": "US",
    "sunrise": 1560343627,
    "sunset": 1560396563
  },
  "timezone": -25200,
  "id": 420006353,
  "name": "Mountain View",
  "cod": 200
  }      

I would like to be able to return the expected response and fetch this data on the first request. Comparing the two sets of data, it seems I am missing the coords object and the weather array at the very top of the expected response.

Please find two files below my functional component and my usefetch hook:

WeatherContainer.js

const WeatherContainer = () => {
  const {latitude, longitude, status} = useGeolocation();
  const apiURL = `https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${globalVariables.API_KEY}`;

  const {result, isLoading, error} = useFetch(apiURL);

  return (
    <View style={styles.container}>
      <View style={styles.innerContainer}>
        <Text>{latitude}</Text>
        <Text>{longitude}</Text>
        <Text>{roundTemp(result.main.temp - globalVariables.KELVIN)}</Text>
      </View>
    </View>
  );
};

export default WeatherContainer;

useGeolocation.js

useGeolocation.js
const useGeolocation = () => {
  const [latitude, setLatitude] = useState(null);
  const [longitude, setLongitude] = useState(null);
  const [status, setStatus] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    const getLocation = async () => {
      const androidGranted = await PermissionsAndroid.request(
        PermissionsAndroid.PERMISSIONS.ACCESS_FINE_LOCATION,
      );
      if (androidGranted == PermissionsAndroid.RESULTS.GRANTED) {
        setStatus('User accepted geolocation services');

        Geolocation.getCurrentPosition(
          position => {
            setLatitude(position.coords.latitude);
            setLongitude(position.coords.longitude);
            console.log(position);
          },
          error => {
            console.log(error.code, error.message);
            setError(error.message);
          },
          {enableHighAccuracy: true, timeout: 15000, maximumAge: 10000},
        );
      } else if (Platform.OS === 'ios') {
        setStatus('User accepted geolocation services');
        Geolocation.requestAuthorization();
      } else {
        setStatus('User denied geolocation services');
      }
    };
    getLocation();
  }, []);

  return {latitude, longitude, status, error};
};

useFetch.js

const useFetch = url => {
  const [result, setResult] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState(null);

  useEffect(() => {
    const getData = async () => {
      setIsLoading(true);
      try {
        await fetch(url)
          .then(res => res.json())
          .then(json => {
            setResult(json);
            console.log(json);
          });
      } catch (error) {
        console.log('Error from fetch: ', error);
        setError(error);
      } finally {
        setIsLoading(false);
      }
    };
    getData();
  }, [url]);

  return {result, isLoading, error};
};

export default useFetch;

Note: All imports are included within my editor. However, if I need to include these then I will on request.

Thank you for taking the time to read.

Tom

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.