Adding Google Maps to angular using RequireJS

New method

Since I wrote this post many things changed on the plugin and what this post explains isn’t valid anymore unless you are still using the old plugin. I wrote another article about how to include Google Maps in your AngularJS App using the new plugin.

Navigate to the new method.

WARNING: This method is deprecated

I was trying to use Google Maps in an Angular application and load all its modules, directives, etc. using RequireJS. This gave me some headache due to this:

  • Google Maps API prefers to be written into the page on document load, so it can use the document.write. But as we are loading it asynchronously, it will require the DOM to be ready to be added.
  • Angular Google Maps plugin requires Google Maps API to be loaded, as it’s an extension of that other and expects its parent to be there to instantiate a map object.
  • The angular app needs the plugin to be loaded as it is a dependency.

Which means that our angular app needs to wait for the plugin to be loaded as it’s a dependency. The plugin needs to wait for GMaps API as its an extension of this one and can’t be loaded without its parent, GMaps will need the DOm to be ready. And we are going to set all that up using RequireJS.

Loading GMaps asynchronously

First of all, we need to be able to load GMaps API after the DOM is ready, so not using document.write. We’ll need to download these RequireJS plugins and one of them, the async one, will help us with this.

require(['async!http://maps.google.com/maps/api/js?sensor=false');

Just as a reminder, apart from downloading the plugins you need to tell Require to load them, so on your main require config you need to add something like this:

requirejs.config({
    paths: {
        // { ... } 

        // require plugins
        , async: 'requirePlugins/async'  // You only need this one
        //, font: 'requirePlugins/font'
        //, goog: 'requirePlugins/goog'
        //, image: 'requirePlugins/image'
        //, json: 'requirePlugins/json'
        //, noext: 'requirePlugins/noext'
        //, mdown: 'requirePlugins/mdown'
        //, propertyParser : 'requirePlugins/propertyParser'

    }

    // { ... } 

});

That allows us to request the GMaps API asynchronously but to set up the dependency our plugin has, we are going to need to define it as a module like this (thank you Miller!):

define('gmaps', ['async!http://maps.google.com/maps/api/js?v=3&sensor=false'],
function () {
    // return the gmaps namespace for brevity
    return window.google.maps;
});

Setting up the plugin on RequireJS

Ok, we know now how to set up GMaps API as an AMD module in RequireJS, but let’s see how to make use of it and include it into our angular app:

I’ve made a requireJS file (angularGoogleMaps.js) that configures all the plugin requirements and can be called from our main require file when building the app.

requirejs.config({
    paths: {
        angularGMapsPlugin: "angular-google-maps-1.2.0.min"
    },
    shim: {
        angularGMapsPlugin: { deps: ["gmaps"] }
    }
});

// convert Google Maps into an AMD module
define('gmaps', ['async!http://maps.google.com/maps/api/js?v=3&sensor=false'],
function () {
    // return the gmaps namespace for brevity
    return window.google.maps;
});


define(['gmaps', 'lodash', 'angularGMapsPlugin']);

Just in case, these are the plugins I’m using:

The plugin “angular-google-maps” also requires lodash to work, which is actually another dependency. I’ve set the order on the define and that should just work but you can also add it to the config if necessary.

Adding it to our angular app

Now that we have defined our angularGoogleMaps.js, let’s make require get it for our application, as easy as calling our file from the main bootstrap:

requirejs.config({
    paths: {
        controllers: "myApp/controllers/_index"
        , services: "myApp/services/_index"
        , models: "myApp/models/_index"
        , directives: "myApp/directives/_index"
        , filters: "myApp/filters/_index"
        , GMapsPlugin: "myApp/angularGoogleMaps" // I dont really load it this way, but just as an example
    }

    , shim: {
        "myApp": {
            deps: [
                "angular", "angular-route", "ui_bootstrap", "jquery"
                , "controllers"
                , "services"
                , "models"
                , "directives"
                , "filters"
                , "GMapsPlugin"  // Dependency added!!
            ]
        }
    }
});

// Just bootstrapping myApp:
require(["scriptsConfig.js"], function () {
    require(["jquery", "angular", "lodash", "myApp"], function ($, ng) {

        $(function () {
            ng.bootstrap(document.getElementsByTagName("messaging-center")[0], ["myApp"]);
        });

    });
});

And finally, myApp has google-maps as a dependency:

var app = angular.module('myApp', ['ngRoute', 'ui.bootstrap', 'google-maps']);

3 thoughts on “Adding Google Maps to angular using RequireJS

  • Hi there, thanks for the article, I’ve technically got this working though I am getting an annoying error. It appears that requirejs is attempting to load gmaps.js based on the code below:

    requirejs.config({
    paths: {
    angularGMapsPlugin: “angular-google-maps-1.2.0.min”
    },
    shim: {
    angularGMapsPlugin: { deps: [“gmaps”] }
    }
    });

    Which makes sense since gmaps at that point is not defined. Am I missing something here?

  • Heeeeeeeeeeeello, I usually don’t pay attention to comments here and missed yours, but in case you are still wondering, I presume you forgot to define “gmaps” as you suggest, which is explained at the beginning of the post, sorry I didn’t make any “summary” in the end with all the code together to make it quicker :s

Leave a Reply

Close Bitnami banner
Bitnami