0

I have a function that fetches the user's geolocation. it works. Now, I want to send this data to my server. I have used a simple then/catch promise. But the then callback is executed before the geolocation function finishes. How to fix this?

Here is the code:

const fetchGeoLocation: SearchService["fetchGeoLocation"] = async () => {
  const geo = navigator.geolocation;
  if (!geo) throw new Error("error.geolocation-unavailable");
  const handleError = (err: any) => {
    if (err.code === 1) throw new Error("error.geolocation-permission_denied");
    if (err.code === 2) throw new Error("error.geolocation-unavailable");
    if (err.code === 3) throw new Error("error.geolocation-timeout");
  };
  const handleSuccess = (position) => {
    return { location: [position.coords.longitude, position.coords.latitude] };
  };
  geo.getCurrentPosition(handleSuccess, handleError, { maximumAge: 10000 });
};


  const onUpdateLocation = async () => {
    onLoad();
    fetchGeoLocation()
      .then((res) => onSave(res.data))
      .catch(({ message }) => onError(message));
  };

The error is:

can't read data of undefined

This error displays before fetchGeoLocation finishes. Also, fetchGeoLocation gives a correct result a shortly afterwards.

How to fix this?

I have tried a different strategy, without any promise, to simply catch an error:

// same as above but no "async" function
const fetchGeoLocation: SearchService["fetchGeoLocation"] = () => {
  const geo = navigator.geolocation;
  if (!geo) throw new Error("error.geolocation-unavailable");
  const handleError = (err: any) => {
    if (err.code === 1) throw new Error("error.geolocation-permission_denied");
    if (err.code === 2) throw new Error("error.geolocation-unavailable");
    if (err.code === 3) throw new Error("error.geolocation-timeout");
  };
  const handleSuccess = (position) => {
    return { location: [position.coords.longitude, position.coords.latitude] };
  };
  geo.getCurrentPosition(handleSuccess, handleError, { maximumAge: 10000 });
};

  const onUpdateLocation = async () => {
    try {
      onLoad();
      const newLocation = await fetchGeoLocation();
      onSave(newLocation);
    } catch (err) {
      onError(err.message);
    }
  };

To test it, I have disabled the geolocation feature on my browser. The error appears in my console, but never reaches the catch block.

How to fix this?

Roamer-1888
  • 19,138
  • 5
  • 33
  • 44
DoneDeal0
  • 5,273
  • 13
  • 55
  • 114
  • 1
    because you are not returning anything from `fetchGeoLocation` – derpirscher Feb 06 '21 at 18:31
  • 1
    You cannot `return` or `throw` from `handleError`/`handleSuccess`. You must properly [promisify](https://stackoverflow.com/q/22519784/1048572) the API – Bergi Feb 06 '21 at 18:33
  • Could you please show me how to do it? I wrapped the geo.getCurrentPosition() with a new Promise() but it doesn't work. – DoneDeal0 Feb 06 '21 at 18:46
  • have you looked at the linked question? – derpirscher Feb 06 '21 at 19:16
  • Yes, but I didn't managed to correctly implement the solution with the complete error handling. I eventually got the answer elsewhere. Thanks a lot for your help! – DoneDeal0 Feb 06 '21 at 19:23

0 Answers0