Anto
Anto

Reputation: 4305

Updating values in async await

I have developed this little piece of code that gets the current lat and lon and pass them to the Google Map URL for fetching map data.

The lat and lon variables are set initially to undefined and then their value is updated when navigator.geolocation.getCurrentPosition is called. This function does return the data correctly via the position object. Somehow however the values of the variables are not updated and they remain undefined when they are passed to the URL.

Where is the problem?

const getLocationDetails = async () => {

    let lat = undefined;
    let lon = undefined;

    await navigator.geolocation.getCurrentPosition( position => {
        lat = position.coords.latitude;
        lon = position.coords.longitude;
    });
    const res = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${lat},${lon}`,
        { method: 'GET' });
    const response = await res.json();

};

Upvotes: 2

Views: 848

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1074989

getCurrentPosition doesn't return a promise, so await is a no-op there and the function does not pause waiting for the operation getCurrentPosition starts to complete. Execution just continues right away¹ when you await something that isn't a promise.

Instead, give yourself a promise-enabled version of it:

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

then use it:

const getLocationDetails = async () => {
    let {coords: {latitude, longitude}} = await asyncGetCurrentPosition();
    const res = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?latlng=${latitude},${longitude}`,
        { method: 'GET' });
    // Note: Missing a `res.ok` check here
    const response = await res.json();
};

(The let {coords: {latitude, longitude}} = .. part of that is destructuring assignment taking coords.latitude and coords.longitude and putting them in latitude and longitude variables, respectively. Then I've updated the fetch to use latitude and longitude [instead of lat and lon]. Could also use const here, since you don't change latitude and longitude. Matter of style.)


¹ When I say "continues right away" above, that's a bit of an overstatement. The code after the await is scheduled to be run in the microtask queue when the current task (or microtask) is complete. So there's a brief delay, but it doesn't wait for getCurrentPosition to finish its work. That's the main point.

Upvotes: 8

Related Questions