I am trying to write a re-usable drop-in Module to load Google Maps
asynchronously and return a promise.
Here is the code I came up with, using AngularJS.
However, there is a re-usability drawback of creating a global callback function "behind the scene". Which is a side effect that may result in bugs, if the same namespace happens to be used by any other library.
My questions - is there any way to achieve this effect without creating global variables.
Below is the code that creates that "evil" global callback:
// Google async initializer needs global function, so we use $window
angular.module('GoogleMapsInitializer')
.factory('Initializer', function($window, $q){
// maps loader deferred object
var mapsDefer = $q.defer();
// Google's url for async maps initialization accepting callback function
var asyncUrl = 'https://maps.googleapis.com/maps/api/js?callback=';
// async loader
var asyncLoad = function(asyncUrl, callbackName) {
var script = document.createElement('script');
//script.type = 'text/javascript';
script.src = asyncUrl + callbackName;
document.body.appendChild(script);
};
// Here is the bad guy:
// callback function - resolving promise after maps successfully loaded
$window.googleMapsInitialized = function () {
mapsDefer.resolve();
};
// loading google maps
asyncLoad(asyncUrl, 'googleMapsInitialized');
return {
// usage: Initializer.mapsInitialized.then(callback)
mapsInitialized : mapsDefer.promise
};
})