2
\$\begingroup\$

I'm checking users locations with HTML Geolocation before unlocking the front door. Geolocation takes a few seconds in addition to the time it takes the user to approve it, so currently I have a callback for what to do next.

function getLocationWithCallbacks(callback, error_callback) {
  navigator.geolocation.getCurrentPosition(
      function (position) {
        let location = { "latitude": position.coords.latitude, "longitude": position.coords.longitude };
        callback(location);
      },
      function (error) {
        if (error.code === error.PERMISSION_DENIED)
          error_callback()
      }
  )
}

And I call this function like so..

getLocationWithCallbacks(unlock_request, get_location_denied);

However, I'm not sure if there's a more logical way than this. It would be nice if events happened in a more linear fashion like ("pseudo code")...

function getLocation() {
  navigator.geolocation.getCurrentPosition(
   function(position) { return ['success', position] },
   function(error) { return ['failure', error] }
}

And invoke it with...

let response = getLocation();
response[0] === 'success' ? unlock_request(response[1]) : get_location_denied(response[1])

However I believe this would involve adding promises and await statements which might make the original callback method more desirable.

I'm just not sure what's the cleanest, most logical way of implementing a getLocation function?

\$\endgroup\$
4
\$\begingroup\$

Most native functions require callback instead of Promise because they support older browsers, so what you have to do is to pack the method in a Promise

function getLocation() {
    return new Promise(function(resolve, reject){ 
        navigator.geolocation.getCurrentPosition(
            function(position) { resolve(position); },
            function(error) { reject(error); }
        }
    });
}

Now are able to determine what should happen with the position and the error.

const response = getLocation()
    .then(position => 
        ( {"latitude": position.coords.latitude, 
           "longitude": position.coords.longitude} ))
    .then(latLong => { unlock_request(latLong) }, 
          error => { get_location_denied(error[1]) });

You know that for this request that you want to get the latitude and longitude out of position so you just return a new object with longitude and latitude, the smart thing with promises is that is it a builder pattern, so can call then again and now the parameter will be what was returned in the last then, so all power is given to response rather than getLocation()

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.