Load Google Maps with RequireJS

If you're using ReuireJS to load your dependencies and wish to load Google Maps asyncronously this explains how.
If you're not familiar with setting up RequireJS, this blog explains how (In SilverStripe CMS context).

Approach 1 (Recommended)

  1. To load Google Maps with RequireJS, you will need to load the Google Maps AMD Loader Plugin.

    bower install --save googlemaps-amd
  2. To load asynchronously, load RequireJS Plugins.

    bower install --save requirejs-plugins
  3. Update your RequireJS configs and paths.

    requirejs.config({
    	baseUrl: '/themes/envmon/javascript/lib',
    	paths: {
    		app: '../app',
    		...
    		googlemaps: '/themes/envmon/bower_components/googlemaps-amd/src/googlemaps',
    		async: '/themes/envmon/bower_components/requirejs-plugins/src/async'
    
    	}
    });
  4. Require in your module.

    define(['jquery', 'googlemaps!'], function ($, gmaps) { ... }
  5. Replace all google.maps instances with gmaps.

Approach 2

  1. Install RequireJS Plugins to be able to use the async loader.
  2. Reference the new plugins in your RequireJS paths

    requirejs.config({
    	baseUrl: '/themes/newtheme/javascript/lib',
    	paths: {
    		app: '../app',
    		jquery: 'jquery-2.1.4/jquery-2.1.4.min',
    		...
    		// RequireJS Plugins
    		async: 'requirejs-plugins/async',
    		font: 'requirejs-plugins/font',
    		goog: 'requirejs-plugins/goog',
    		image: 'requirejs-plugins/image',
    		json: 'requirejs-plugins/json',
    		noext: 'requirejs-plugins/noext',
    		mdown: 'requirejs-plugins/mdown',
    		propertyParser : 'requirejs-plugins/propertyParser'
    
    	},
    	shim: { ... }
    	}
    });
  3. In your module load Google Maps:
    Note: Place the Google Maps require string at the end and you will not need to pass an argument for Google Maps, i.e. note we only have function($) and not function($, google).

    define(['jquery', 'async!http://maps.google.com/maps/api/js?sensor=false'], function ($) {
    
    	controller.setModel(model);
    	google.maps.event.addDomListener(window, 'load', initializeMap);
    
    	function initializeMap() {
    
    		var myLatlng = new google.maps.LatLng(-41.2443701,174.7618546);
    		var mapOptions = {
    			zoom: 9,
    			center: myLatlng
    		}
    
    		// Assuming your map DIV in your HTML has ID "map-canvas"
    		mapCanvas = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    
    	}
    
    });

Approach 3

An alternative approach is to use the Google Maps loader module.

  1. Download the Google Maps Loader module and add to the lib folder.
  2. Load module in paths.

    requirejs.config({
    	baseUrl: '/themes/newtheme/javascript/lib',
    	paths: {
    		app: '../app',
    		jquery: 'jquery-2.1.4/jquery-2.1.4.min',
    		...
    		googleMapsLoader: 'google-maps-loader'
    	},
    	shim: { ... }
    	}
    });
  3. Load the Google Maps Loader mod.

    define(['jquery', 'googleMapsLoader'], function ($, jqueryui, googleMapsLoader) {
    
    	controller.setModel(model);
    	googleMapsLoader.done(function(GoogleMaps){
    
    		var myLatlng = new google.maps.LatLng(-41.2443701,174.7618546);
    		var mapOptions = {
    		zoom: 9,
    		center: myLatlng
    		}
    
    		mapCanvas = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
    
    	}).fail(function(){	
    		console.error("ERROR: Google maps library failed to load");
    	}); 
    });

References
https://github.com/aerisweather/googlemaps-amd (Approach 1)
https://github.com/millermedeiros/requirejs-plugins
 (Approach 2)
http://www.remwebdevelopment.com/blog/javascript/getting-google-maps-to-work-with-requirejs-22.html (Approach 2)
https://gist.github.com/MattSurabian/7868115 (Approach 3)