Home > front end >  Creating a function to get user location in React Native logging but not returning the updated value
Creating a function to get user location in React Native logging but not returning the updated value

Time:08-15

I'm writing the below function that should get the user's current location and then update the predefined location properties:

export const getCurrentLocation = () => {
  const location = {
    userLat: '5',
    userLng: ''
  }

  navigator.geolocation.getCurrentPosition(
    (position) => {
      //getting the Longitude from the location json
      const currentLongitude = JSON.stringify(position.coords.longitude);

      //getting the Latitude from the location json
      const currentLatitude = JSON.stringify(position.coords.latitude);

      location.userLat = currentLatitude;

      console.log('lat: ', location.userLat);
    },
    (error) => {
      console.warn(error);
    },
    {
      enableHighAccuracy: false,
      timeout: 30000,
      maximumAge: 1000
    },
  );
  return (
    location
  );
}

I equated location.userLat to currentLatitude and this logs correctly on the console, however when the function is done running, the produced userLat is still its initial value of 5. I alternatively tried using useState hooks to update the value but got the error of invalid hook calls. Any tips or suggestions on how to make it reflect the currentLatitude value will be appreciated.

CodePudding user response:

From what I can tell it seems that getCurrentPosition is an asynchronous function. Note that this doesn't mean it's declared async or that it returns a Promise object that can be await-ed on.

You can convert your getCurrentLocation function to an async function and wrap the getCurrentPosition call in a Promise.

const getCurrentPosition = (options) => {
  return new Promise((resolve, reject) => {
    return navigator.geolocation.getCurrentPosition(resolve, reject, options))
  };
};

export const getCurrentLocation = async (options) => {
  const location = {
    userLat: '5',
    userLng: ''
  };

  try {
    const position = await getCurrentPosition(options);

    //getting the Longitude from the location json
    const currentLongitude = JSON.stringify(position.coords.longitude);

    //getting the Latitude from the location json
    const currentLatitude = JSON.stringify(position.coords.latitude);

    location.userLat = currentLatitude;
    location.userLng = currentLongitude;

    console.log('lat: ', location.userLat);
  } catch(error) {
    console.warn(error);
  }

  return location;
}

Consuming code:

const options = {
  enableHighAccuracy: false,
  timeout: 30000,
  maximumAge: 1000,
};

const { userLat, userLng } = await getCurrentLocation(options);

CodePudding user response:

As @Drew stated getting the location is happening asynchronously, so that retun is happening before the console log. Another way of talking this is to transform your function to a hook, so you will be able to use useState. Like so:

import { useEffect, useState } from "react";
export const useGgetCurrentLocation = () => {
  const [location, setLocation] = useState({
    userLat: "",
    userLng: "",
  });
  const [fetchingLocation, setFetchingLocation] = useState(true);
  const [error, setError] = useState("");

  useEffect(() => {
    navigator.geolocation.getCurrentPosition(
      (position) => {
        setLocation({ userLat: position.coords.latitude, userLng: position.coords.longitude });
        setFetchingLocation(false);
      },
      (error) => {
        console.warn(error);
        setError("Something went wrong!");
        setFetchingLocation(false);
      },
      {
        enableHighAccuracy: false,
        timeout: 30000,
        maximumAge: 1000,
      }
    );
  }, []);

  return { location, fetchingLocation, error };
};

And you would use it as below. First you would get fetchingLocation containing true, then it becomes false, and whether the location is successful or not, you would get error containing a message or location containing the actual latitude and longitude.

const { location, fetchingLocation, error } = useGgetCurrentLocation();
  • Related