Wednesday, June 1, 2016

Harnessing the Google Maps JavaScript API the Right Way

Google Maps icon

Google Maps is an online mapping service providing up-to-date road maps, business listings, directions, street-level photos and more.

There are notable alternatives to Google Maps, such as Mapbox and Open Street Map. But in my view, none of the competitors can match up to Google Maps for the sole reason of the completeness of its business directory. Google is able to present a complete and vast map equipped with up-to-date business details, thanks mainly to the crossover with their search offering.

There are various APIs for interacting with Maps, from the simple Static API to the powerful JavaScript API, which is the focus of this article.

Of course, you can place Google Maps on your site without leveraging the various APIs on offer. This makes life easier, of course, and still offers a lot of useful features. But the Maps JavaScript API gives us full control over our map for performance and customization purposes.

Google Maps JavaScript API

In this article, I'd like to show you how to make the most of the Maps JavaScript API --- using it the right way.

There are lots of tutorials and examples already out there for this, but too often without a focus on the best way of achieving the desired result. They get things done quickly, but without a considered approach or explanation of why certain steps have been taken.

The complete source code for this article can be found on our GitHub repo.

Creating a Basic Map Canvas

The first thing we need to do is set up a simple front-end framework for building the mapping application.

Create the HTML

Let's create an HTML file with the following markup:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Google Maps API Template</title>

    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div id="map"></div>

    <script src="script.js" defer></script>
  </body>
</html>

This gives us a robust platform for building a full mapping application.

Notice how we've used the defer attribute for our script. This tells the browser to download the specified scripts as soon as possible, but to wait until HTML parsing has finished before executing them. It's important to use defer whenever possible, as it will prevent the rendering of the page from halting before it's finished in order to execute JavaScript code --- providing a janky loading experience for the user. The eagle-eyed reader may notice how we haven't included Google Maps' JavaScript: this is deliberate, and will be explained shortly!

Build the on-ready callback

Now, let's set up our initial JavaScript file, script.js, starting with the document.addEventListener('DOMContentLoaded', function () {}) call:

document.addEventListener('DOMContentLoaded', function () {
  if (document.querySelectorAll('#map').length > 0)
  {
    if (document.querySelector('html').lang)
      lang = document.querySelector('html').lang;
    else
      lang = 'en';

    var js_file = document.createElement('script');
    js_file.type = 'text/javascript';
    js_file.src = 'http://ift.tt/1TKijCN' + lang;
    document.getElementsByTagName('head')[0].appendChild(js_file);
  }
});

The #map length check is a quick way to find out if a certain element is present on the current page. Quite often, the same external JavaScript file will be included on an entire website, and quite often some portions of code are only required for certain pages. In this instance, we only ever want to execute this code if we're presenting a map canvas to the user. This prevents unnecessary code bloat on pages that don't require it. (Performance matters!)

Once we're sure we have a map canvas on the page, we may think we're ready to proceed, but there's one more check we should perform. By default, the Google Maps JavaScript API loads in English, regardless of what language the requesting page is in. A great way to counteract this is to set a lang variable based on the lang attribute in the <html> element. This will allow us to include the Google Maps JS in the correct language for our user. This is especially useful for multilingual (i18n) websites that include the same script.js file across all languages.

Grabbing Google's JavaScript file

Now comes the time to load the external Google Maps JS file. The reason we've left it until now, rather than including it as a regular <script> tag in the HTML, is to prevent unnecessary code bloat in pages that don't have a map canvas. To load in the file, we create a new <script> element and inject it into the <head> of the DOM. As Google's API handles callbacks for us, we don't need to do anything more fancy than this:

var js_file = document.createElement('script');
js_file.type = 'text/javascript';
js_file.src = 'http://ift.tt/283Qf74' + lang;
document.getElementsByTagName('head')[0].appendChild(js_file);

There are a few interesting things to note in the query string parameters passed to the API.

Firstly, we pass our lang variable as the language parameter to instruct Google on which language we want the map to be in.

Secondly, we provide the signed_in parameter as true. This is to increase the personalization of the map (e.g. it will have your starred locations visible, amongst other things).

Next, we pass the key parameter with our API key (more on that shortly).

Finally, and most importantly, we specify our callback function using the callback parameter. This tells Google which of our functions it should trigger once the file has been fetched successfully.

Google Maps JS API will still work without a valid key parameter. However, we would be issued with a JavaScript error console warning message. So we should make sure we get ourselves a free API key by following Google's guide.

Initializing the map canvas

Now that we've got our initialization function call set up, we can move on to defining our callback function initMap(). This is the function that the Google Maps JS API will trigger once it's successfully loaded.

var map;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: -34.397, lng: 150.644},
    zoom: 8
  });
}

When creating a new Google Map, it's best to create the variable for the map in the global scope (outside of any functions) so that it's easier to interact with the map later. This is why we define map outside of initMap().

Now that we've got an empty map variable to work with, we can go ahead and assign the Google Map object to it inside the initMap() function. This is exactly as Google's Simple Map example. One important thing to note is that we must specify both a center and a zoom, or the map will not initialize at all. There is no default!

Don't forget the CSS

One last important step to getting the initial basic map canvas to function is to provide some CSS in our style.css file:

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
}

#map {
  height: 100%;
}

The most common pitfall we'll cover today is forgetting to set a height attribute for the #canvas element. Regardless of everything else covered in this article, if there's no height (or min-height) CSS attribute set, we won't see a map at all. The styles applied to <html> and <body> are only there to allow the canvas to be full-screen.

Google map without markers

Continue reading %Harnessing the Google Maps JavaScript API the Right Way%


by Jamie Shields via SitePoint

No comments:

Post a Comment