Tutorial

Using the Geolocation API

Published on October 27, 2017
Default avatar

By Alligator.io

Using the Geolocation API

While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.

The Geolocation API is a very simple API that allows to get a device’s current location coordinates. It has only two methods: getCurrentPosition and watchPosition and the data returned is very straightforward, but when coupled with a mapping API, complex location-aware web apps can be created.

Setup

Before doing anything, you’ll want to check if the API is available in the user’s browsers:

if (navigator.geolocation) {
  // 🗺️ yep, we can proceed!
} else {
  // no can do
}

Note that your website or app has to be served over https for the API to work. For local development, you’ll want to run a local server instead of opening an html file directly. If you have npm 5.2 or above available on your machine, you can use npx to quickly run an http server:

$ npx http-server

getCurrentPosition

Use the getCurrentPosition method to get the user’s coordinates once. The first and only required argument should be a success callback function that will be called with a position object if the position request is successful.

Here’s a simple example that prints out the device’s longitude and latitude to the console:

if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(displayLocationInfo);
}

function displayLocationInfo(position) {
  const lng = position.coords.longitude;
  const lat = position.coords.latitude;

  console.log(`longitude: ${ lng } | latitude: ${ lat }`);
}

Here’s the shape and example data of the position object that’s passed to the success callback:

coords:
  accuracy: 52
  altitude: null
  altitudeAccuracy: null
  heading: null
  latitude: 27.380583
  longitude: 33.631839
  speed: null
timestamp: 1509152059444

As you can see from the above example, some of the properties for coords may have a value of null. The availability of the data will depend on the capabilities of the device that’s under use. The heading value, if any, will be in degrees relating to true North and going clockwise and the speed value, if any, will be in meters per second.

Permission

Because position information is potentially sensitive, the first time a domain makes a call to get a user’s position, the browser will ask the user for permission by showing a widget that looks a little bit like this:

Geolocation permission widget

If the user refuses access, the error callback, if any, will be called with an error code of 1 (PERMISSION_DENIED).

watchPosition

There’s also a watchPosition method that will return new position data each time the device changes position significantly.

In the following example, we initiate a position watcher and then stop it after 15 seconds:

const watcher = navigator.geolocation.watchPosition(displayLocationInfo);

setTimeout(() => {
  navigator.geolocation.clearWatch(watcher);
}, 15000);

function displayLocationInfo(position) {
  // ...do something with the data each time
}

We use clearWatch with a watcher id to stop watching for position data.

Error Handling

You can provide an error handler callback as the second argument to either getCurrentPosition or watchPosition. If the error callback is called, an error object will be passed-in and will contain a code property that will have a value of 3 (TIMEOUT), 2 (POSITION_UNAVAILABLE) or 1 (PERMISSION_DENIED), depending on the nature of the error.

Here’s a simple example where we trigger an automatic error by setting a timeout value of 0ms:

navigator.geolocation.getCurrentPosition(displayLocationInfo, handleLocationError, { timeout: 0 });

function displayLocationInfo(position) {
  // ...do stuff
}

function handleLocationError(error) {
  switch (error.code) {
    case 3:
      // ...deal with timeout
      break;
    case 2:
      // ...device can't get data
      break;
    case 1:
      // ...user said no ☹️
  }
}

Options

Finally, you can pass-in a third argument with options for the following:

  • enableHighAccuracy: Takes a boolean value and defaults to false. Indicates if the position information should be as accurate as possible (more accuracy may be more costly in terms of CPU and battery usage).
  • maximumAge: Number of milliseconds to keep position data cached for. It defaults to a value of 0.
  • timeout: Number of milliseconds after which the error callback will be called if no data has been acquired.

Here’s an example with options passed-in for maximumAge and timeout:

navigator.geolocation.getCurrentPosition(
  displayLocationInfo,
  handleLocationError,
  { maximumAge: 1500000, timeout: 0 }
);

function displayLocationInfo(position) {
  const lng = position.coords.longitude;
  const lat = position.coords.latitude;

  console.log(`longitude: ${lng} | latitude: ${lat}`);
}

function handleLocationError(error) {
  switch (error.code) {
    case 3:
      // timeout was hit, meaning nothing's in the cache
      // let's provide a default location:
      displayLocationInfo({ coords: { longitude: 33.631839, latitude: 27.380583 } });

      // now let's make a non-cached request to get the actual position
      navigator.geolocation.getCurrentPosition(displayLocationInfo, handleLocationError);
      break;
    case 2:
      // ...
      break;
    case 1:
    // ...
  }
}

If there’s cached position data that’s available and that’s a maximum of 25 minutes old (1500000ms) we return that. If not, we error-out immediately (using a timeout of 0ms). In the error handler case for a timeout, we provide a default location value and then make another call to get fresh location data. This way, the app can avoid showing a blank state while fresh position data is being gathered.

Browser Support

Can I Use geolocation? Data on support for the geolocation feature across the major browsers from caniuse.com.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about us


About the authors
Default avatar
Alligator.io

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel