Skip to content

Instantly share code, notes, and snippets.

@gbakernet
Created February 15, 2011 23:42
Show Gist options
  • Save gbakernet/828536 to your computer and use it in GitHub Desktop.
Save gbakernet/828536 to your computer and use it in GitHub Desktop.
Load Google Maps API using jQuery Deferred.
/*!
* JavaScript - loadGoogleMaps( version, apiKey, language )
*
* - Load Google Maps API using jQuery Deferred.
* Useful if you want to only load the Google Maps API on-demand.
* - Requires jQuery 1.5
*
* Copyright (c) 2011 Glenn Baker
* Dual licensed under the MIT and GPL licenses.
*/
/*globals window, google, jQuery*/
var loadGoogleMaps = (function($) {
var now = $.now(),
promise;
return function( version, apiKey, language ) {
if( promise ) { return promise; }
//Create a Deferred Object
var deferred = $.Deferred(),
//Declare a resolve function, pass google.maps for the done functions
resolve = function () {
deferred.resolve( window.google && google.maps ? google.maps : false );
},
//global callback name
callbackName = "loadGoogleMaps_" + ( now++ ),
// Default Parameters
params = $.extend(
{'sensor': false}
, apiKey ? {"key": apiKey} : {}
, language ? {"language": language} : {}
);;
//If google.maps exists, then Google Maps API was probably loaded with the <script> tag
if( window.google && google.maps ) {
resolve();
//If the google.load method exists, lets load the Google Maps API in Async.
} else if ( window.google && google.load ) {
google.load("maps", version || 3, {"other_params": $.param(params) , "callback" : resolve});
//Last, try pure jQuery Ajax technique to load the Google Maps API in Async.
} else {
//Ajax URL params
params = $.extend( params, {
'v': version || 3,
'callback': callbackName
});
//Declare the global callback
window[callbackName] = function( ) {
resolve();
//Delete callback
setTimeout(function() {
try{
delete window[callbackName];
} catch( e ) {}
}, 20);
};
//Can't use the jXHR promise because 'script' doesn't support 'callback=?'
$.ajax({
dataType: 'script',
data: params,
url: 'http://maps.google.com/maps/api/js'
});
}
promise = deferred.promise();
return promise;
};
}(jQuery));
$(elem).on("myevent", function() {
$.when( loadGoogleMaps( 3, API_KEY, LANG ) )
.then(function() {
!!google.maps // true
});
});
// OR
$(elem).on("myevent", function() {
loadGoogleMaps( 3, API_KEY, LANG )
.done(function() {
!!google.maps // true
});
});
@kenaniah
Copy link

kenaniah commented Sep 2, 2011

This returns a different deferred object every time you call it. Instead, the deferred object ought to be cached like a singleton. Please see changes to code below (since I don't use git):

add at line 17:

if(this.deferred) return this.deferred.promise();

add above line 75:

this.deferred = deferred;

@gbakernet
Copy link
Author

Thanks for the reminder, I had this change in my local project but hadn't updated the Gist.

Copy link

ghost commented Feb 3, 2012

hi, thank you for sharing this code.
which object should I use with the jquery $.when() function to know when the loading is all complete?
Something like

loadGoogleMaps ('3.6', 'key', 'it');

$.when(loadGoogleMaps).then(function() { alert('gmaps is ready!'); });

@gbakernet
Copy link
Author

No probs!

It returns a promise which is subset of Deferred. You can use http://api.jquery.com/jQuery.when/ as you have suggested or you can use the promise directly http://api.jquery.com/deferred.done/

loadGoogleMaps( 3, API_KEY, LANG ).done(function() {
    !!google.maps // true
});

Copy link

ghost commented Feb 3, 2012

thank you, it works if I append the .done() method that way, but oddly it doesn't if I use $.when()

loadGoogleMaps( 3, API_KEY, LANG )

when(loadGoogleMaps).done(function() {
    !!google.maps // true
});

this fires the 'done' anonymous function too early, before all the attached scripts are loaded.
btw I'm using the last method, jquery ajax.

I can rearrange my script to use the way you showed me, but I'd prefer to use $.when() if possible

Copy link

ghost commented Feb 3, 2012

nevermind, i'll just append .done()
it works great, thank you

@gbakernet
Copy link
Author

To use when, you need the promise returned from loadGoogleMaps

$.when( loadGoogleMaps( 3, API_KEY, LANG ) )
    .then(function() {
        !!google.maps // true
    });

@compumatter
Copy link

I would like to thank you. This works perfectly for my needs when it seemed days of efforts would lead only to frustration.
Great function. I used it in the form described by gbakernet
$.when( loadGoogleMaps( 3, API_KEY, LANG ) )
.then(function() {
!!google.maps // true
});

@backflip
Copy link

How about the following

document.location.protocol + '//maps.google.com/maps/api/js'

@lucman
Copy link

lucman commented Jan 24, 2013

you can also use this simple jquery plugin that uses the async mode when loading Google Maps api:

http://lucamanzo-soluzione-software.it/wp/?p=5

Usage example:

$(document).ready(function(){
$.gmapstools.init();
$("#my_map_canvas").gmap({lat:37.4221913, lng:-122.08458530000001, draw_marker:true, zoom_level:13});
});

that's done. The plugin loads the Google Maps API only when you do the call (so... after the dom is ready and the page has been built)

$.gmapstools.init();

@GFoley83
Copy link

GFoley83 commented Jul 8, 2013

Very useful function, thank you!

Forked and updated with following changes:

  • Tidied JS & made it JSLint compliant
  • Updated script request to Google Maps API to be protocol relative
  • Added "sensor" parameter which defaults to false if not present

https://gist.github.com/GFoley83/5953448

@backflip
Copy link

In case anyone wants to load this using Bower, I made a fork of Gavin's fork available:

"dependencies": {
  "load-google-maps": "https://gist.github.com/8613939.git"
}

@spranger
Copy link

spranger commented Dec 4, 2014

How to use your code with a business version of GM via client=gme-xyz ? My regular GM-API to load is http://maps.googleapis.com/maps/api/js?v=3&amp;sensor=false&amp;client=gme-xyz

@enlacee
Copy link

enlacee commented May 26, 2015

GOOD WORKS! this code it's beautiful 😵

@marchrius
Copy link

I added libraries support in my fork

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment