1

I'm trying to get the user location for a weather app but the log return undefined

  const [lat, setLat] = useState();
  const [long, setLong] = useState();

  useEffect(() => {
    const handleLocation = () => {
      navigator.geolocation.getCurrentPosition((position) => {
        setLat(position.coords.latitude);
        setLong(position.coords.longitude);
      });

      console.log(lat);
      console.log(long);
    };

    if (navigator.geolocation) {
      navigator.permissions.query({ name: 'geolocation' }).then(function (result) {
        if (result.state === 'granted') {
          console.log(result.state);
          handleLocation();
        } else if (result.state === 'prompt') {
          console.log('prompt');
        } else if (result.state === 'denied') {
          console.log('Denied');
        }
      });
    }
  }, [lat, long]);

I get the log granted confirming that the browser granted the location but then I get undefined for the lat and long

Rafael
  • 23
  • 3
  • 1
    Does this answer your question? [useState set method not reflecting change immediately](https://stackoverflow.com/questions/54069253/usestate-set-method-not-reflecting-change-immediately) – samuei Mar 29 '21 at 15:05
  • The function you're passing: `(position) => { ... }` runs after your console.log()s. Determining the location takes some time, and the browser isn't supposed to hang during the wait, that's why you have to pass a callback function in the first place. Setting state is also async, so even if getting the location weren't, you'd still get `undefined`. –  Mar 29 '21 at 15:25

4 Answers4

0

I believe this is a simple async problem. The navigator.geolocation.getCurrentPosition is asynchronous and will not call the given function straight away.

I believe if you move your console.log inside the callback, then the state should have the right value.

const handleLocation = () => {
  navigator.geolocation.getCurrentPosition((position) => {
    setLat(position.coords.latitude);
    setLong(position.coords.longitude);
    console.log(lat);
    console.log(long);
  });
};

Also bear in mind that React state updates can be asynchronous. A better way to test the different values of the lat and long variables, would be to log them in the render function.

function Component() {
    const [lat, setLat] = useState()

    useEffect( /* your useEffect callback here */);

    console.log(lat); // you will see all the values of lat through time now
}
atomrc
  • 2,543
  • 1
  • 16
  • 20
0

Found the error being the OS blocking the location service from the browser

Rafael
  • 23
  • 3
0

Put a string in your states;

const [lat, setLat] = useState(""); const [long, setLong] = useState("")

Avoid writing your states this ways:

const [lat, setLat] = useState(); const [long, setLong] = useState();

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Aug 15 '23 at 17:07
0
import { useState, useEffect } from 'react'

function App() {

  const [location, setLocation] = useState({ lat: 0, long: 0 });

  useEffect(() => {

    const onSuccess = (position) => {
      setLocation({
        lat: position.coords.latitude,
        long: position.coords.longitude
      });

      console.log(location.lat);
      console.log(location.long);
    }

    const onError = (error) => {
      console.log(error.message)
    }

    navigator.geolocation.getCurrentPosition(onSuccess, onError);

  }, [location.lat, location.long]);

  return (
    <h2>{`Location: ${location.lat}, ${location.long}`}</h2>
  )
}

export default App
sahilatahar
  • 568
  • 2
  • 13