Random thoughts & observations

From the mundane to the profound and everything in between here’s what’s rocking our world

Using Google Maps in Angular JS

Posted: March 10, 2015
Written by: Saints At Play
Category: AngularJS

Angular JS, once you switch from a jQuery mindset, makes building out web apps relatively quick and thanks to the growing number of available plug-ins you can be sure to find a solution to fit your development needs.

One such need might involve implementing Google Maps which is what we are going to look at through this tutorial.

Prerequisites

To work through and complete this tutotial you'll need the following resources:

  • Google Maps (and API key)
  • AngularJS
  • Lodash
  • Angular Google Maps

To start with though create a directory on your computer where you want to set up your Google Map / AngularJS integration. This is where you'll download all the necessary dependencies and create the actual web page to embed your Google Map using AngularJS.

A project structure akin to the following would work best for not only developing your project but also organising your assets more effectively:

nameOfProjectDirectoryHere
 - css
 - js
   - libraries
   - custom
 - images
 - index.html

You can of course name the project directories or structure them however you see fit but the key point is to make it easy to use and find different files/file types. Once that's done it's time to configure and retrieve the necessary dependencies.

Google Maps

In order to use the Google Maps service there's a couple of steps you'll need to take.

First you'll need to select the correct API (as there are a few different options available depending on your particular needs and how the Maps service will be used) which, for the purposes of displaying on a website or PhoneGap based (or similar) mobile app, will involve using the JavaScript API v3.

Second, you need to obtain an API key which will be used to allow access to and monitor usage of the Maps service. Follow these steps to generate an API key and then, once finished, copy and paste the generated key somewhere safe for use later on in the tutorial (but don't forget where you've saved this!)

AngularJS

As AngularJS will be performing most of the heavy lifting for our project we need to be sure we have this available for use. Download, or link to, the latest version of the framework here.

Angular Maps

Head over to Angular Google Maps and download the latest version of the software which, at the time of writing, is v2.0.16. This script contains a set of directives that allow Google Maps to be integrated into and used with AngularJS. In order to use Angular Google Maps you'll also require lodash, a JavaScript utility library similar to underscore, so be sure to download this to your project folder.

Based on the above project directory structure the dependencies you recently downloaded should be saved within the js/libraries sub-directory like so:

nameOfProjectDirectoryHere
 - css
 - js
   - libraries
     - angular.min.js
     - angular-google-maps.min.js
     - lodash.min.js
   - custom
 - images
 - index.html

This organisation makes managing updates, adding additional dependencies and allowing other team members (if applicable) to work with our project and its assets more effectively.

Off to work we go

Now that you have all the relevant software dependencies and your project directory structure set up its time to start building out your web page and embedding the Google Maps service.

Open your index.html file (if it doesn't exist, quickly create it!) and create links to your dependencies so they can be loaded into and used for the web page:

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
  <script src="js/libraries/lodash.min.js"></script>
  <script src="js/libraries/angular.min.js"></script>
  <script src="js/libraries/angular-google-maps.min.js"></script>
  <script src="js/custom/app.js"></script>
 </head>
 <body>
   
 </body>
</html>

Pay attention to the order in which the above files are loaded: lodash.min.js MUST come before angular.min.js and angular-google-maps.min.js.

The more observant amongst you might have noticed that the following file: js/custom/app.js is also being loaded after our other dependencies have been declared.

This file will contain all the necessary logic to implement our Google Map inside the web page so let's go ahead and start coding this!

App.js

Start with the following code at the top of our file:

"use strict";
angular.module('customMap', ['uiGmapgoogle-maps'])

We start by defining a module, which will be the container for our application, titled customMap and we define a single dependency: uiGmapgoogle-maps, which will be used to gain access to the angular-google-maps directives within our module (without this dependency our application simply won't work as intended).

Next we need to configure a provider for the angular-google-map directives which allows us to accomplish the following:

  • Asynchronously loads the Google Maps service (as recommended by Google themselves)
  • Guarantees that angular-google-maps does NOT begin processing any of the directives UNTIL the Google Maps service is loaded

To accomplish this we need to implement the following script within our app.js file, beneath the module declaration:

.config(function(uiGmapGoogleMapApiProvider) {
 uiGmapGoogleMapApiProvider.configure({
  key: 'THIS-IS-WHERE-YOU-PASTE-THE-MAP-API-KEY-YOU-COPIED-EARLIER',
  v: '3.17',
  libraries: 'weather,geometry,visualization'
 });
})

The defaults for this configuration are as follows:

  • key - The Google Maps API key that you generated earlier
  • v - The version number of the Maps API
  • libraries - The Maps API libraries that we wish to use (more information here)

​Now that the parameters for the angular-google-map have been configured let's create a controller and start defining our map object for use in the index.html file.

Below the configuration for our angular-google-map provider type out the following:

.controller("mapController", function($scope, uiGmapGoogleMapApi) {
  
  // Define variables for our Map object
  var areaLat      = 44.2126995,
      areaLng      = -100.2471641,
      areaZoom     = 3;

  uiGmapGoogleMapApi.then(function(maps) {
    $scope.map     = { center: { latitude: areaLat, longitude: areaLng }, zoom: areaZoom };
    $scope.options = { scrollwheel: false };
  });

});

This defines a controller, called mapController which accepts 2 dependencies: $scope, to allow data within this controller to be bound to the template in which it is implemented and uiGmapGoogleMapApi which allows us to hook into directives provided by the uiGmapgoogle-maps dependency which was defined in our customMap module towards the top of the app.js file.

Within our controller the uiGmapGoogleMapApi promise is implemented which uses a callback method - .then - to allow access to the map object returned by the Google Maps API. Inside this callback method properties for the map are configured using the areaLat, areaLng and areaZoom variables, which were defined at the top of the controller, and these are bound to the $scope object allowing the data to be represented within the view template where the controller will be assigned.

In case you're new to JavaScript promises the following provides an explanation of their purpose:

A promise is a placeholder that represents the result, success or failure, of an 
asynchronous operation - essentially it is a contract that agrees to handle how 
asynchronous requests are dealt with by an application.

Here's our app.js file in full:

"use strict";
angular.module('customMap', ['uiGmapgoogle-maps'])

.config(function(uiGmapGoogleMapApiProvider) {
 uiGmapGoogleMapApiProvider.configure({
  key: 'THIS-IS-WHERE-YOU-PASTE-THE-MAP-API-KEY-YOU-COPIED-EARLIER',
  v: '3.17',
  libraries: 'weather,geometry,visualization'
 });
})

.controller("mapController", function($scope, uiGmapGoogleMapApi) {
  
  // Define variables for our Map object
  var areaLat      = 44.2126995,
      areaLng      = -100.2471641,
      areaZoom     = 3;

  uiGmapGoogleMapApi.then(function(maps) {
    $scope.map     = { center: { latitude: areaLat, longitude: areaLng }, zoom: areaZoom };
    $scope.options = { scrollwheel: false };
  });

});

Embedding the Map

Now that the logic for our map is configured we can start to implement that within our view.

Open up your index.html file and within the body of the document enter the following HTML:

<body ng-app="customMap">
  <div ng-controller="mapController">
    <ui-gmap-google-map center="map.center" options="options" zoom="map.zoom"></ui-gmap-google-map>
  </div>
</body>

The above HTML snippet initialises the app, using the ng-app directive to assign our customMap module to the <body> of the web page, followed by the ng-controller directive which is assigned to a <div> element which, in turn, contains the <ui-gmap-google-map> directive that implements the map options defined in the mapController.

Easy-peezy, lemon squeezy!

Our completed index.html file should now look like this:

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width">
  <script src="js/libraries/lodash.min.js"></script>
  <script src="js/libraries/angular.min.js"></script>
  <script src="js/libraries/angular-google-maps.min.js"></script>
  <script src="js/custom/app.js"></script>
 </head>
 <body ng-app="customMap">
   <div ng-controller="mapController">
     <ui-gmap-google-map center="map.center" options="options" zoom="map.zoom"></ui-gmap-google-map>
   </div>
 </body>
</html>

An important point to be aware of is this - without a height value specified for the map container you simply won't see the google map being rendered to the page. To overcome this you'll need to define the following style rule for the map container:

.angular-google-map-container { 
  height: 300px; // Or whatever pixel value you require :)
}

Whether you choose to embed this style within the web page or inside a separate CSS file linked to your web page is entirely up to you (best practice, which every developer should aspire to, would place that inside an external CSS file).

Now we've come to the end of the tutorial and, if you've followed each step exactly, you should, when previewing the index.html file within a web browser, see a google map embedded within your page!

« Return to Posts

Comments

Gravatar
Riccardo

May 21, 2015

I had the same problem but setting height to 100vh in CSS works
.angular-google-map-container &#123; height: 100vh; &#125;

Gravatar
Ayo

May 19, 2015

Hey Saints,

I was looking for a solution without using JS and tricky methods just to make my code clean.
But I didn't find a solution so I think I will try what you've told me.

Thank you a lot

Gravatar
Saints At Play

May 18, 2015

Hi Ayo,

It's a tricky one. A potential solution might involve using a JS solution to dynamically calculate the height of the browser screen and then apply that to the height of the angular map container area. This might also need to be called inside an onresize/orientationchange event to detect any changes in the size of the screen (I.e. if the phone orientation is changed or the user drags the desktop browser window in/out to change the width of the viewable area.

Hope this helps.

Gravatar
Ayo

May 18, 2015

Hello,

This tuto is great. I have just a question is there anyway to make the Height responsive because specifying the height in pixel is just not perfect and I tried to set it to 100% but it does not work.

Do you have any idea how to set the height to 100% so to be responsive ?

Gravatar
Oliver Ochieng

April 14, 2015

Hello I have just started learning ionicframework I have tried for days to get the map working with no success , can you show me how to implement it in ionic

Posting comments after three months has been disabled.