I’m attempting to understand the Revealing Module Pattern and jQuery Deferreds with a (what I thought was a) simple example.
What I want to be able to do is call a module to get the user’s location and when and if that call succeeds show the location on a google map.
Both of these operations by themselves using a bunch of functions and callbacks are no problem for me, but I have attempted to do it in a more ‘ravioli’ rather than ‘spaghetti’ kind of way.
What I’m finding is that while the deferred is working perfectly, my module’s public properties do not contain the values that I have set during the operation to get the location.
This is my ‘geoModule’
var geoModule = function () {
var lat;
var lng;
var init = function () {
return $.Deferred(function (def) {
getCurrentPositionDeferred({})
.fail(function () { def.reject(); })
.done(function (location) {
lat = location.coords.latitude;
lng = location.coords.longitude;
logger.log("Got location : " + lat + " : " + lng);
def.resolve();
});
}).promise();
};
var getCurrentPositionDeferred = function(options) {
var deferred = $.Deferred();
navigator.geolocation.getCurrentPosition(deferred.resolve, deferred.reject, options);
return deferred.promise();
};
return { lat: lat, lng: lng, init: init };
}();
and this is my ‘mapModule’
var mapModule = function (mapId) {
var mapElement = document.getElementById(mapId);
var map;
var initMap = function (lat, lng) {
logger.log("init map: " +lat + " : " + lng);
var myOptions = {
zoom: 14,
center: new google.maps.LatLng(lat, lng),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
map = new google.maps.Map(mapElement, myOptions);
};
return { initMap: initMap };
}('map');
When I bring them together like this:
$.when(geoModule.init())
.done(function () {
logger.log("location done " + geoModule.lat + " : " + geoModule.lng);
mapModule.initMap(geoModule.lat, geoModule.lng);
});
the geoModule.lat and geoModule.lng are undefined, even thought the code to set them in geoLocation is running successfully.
I’ve created a full example at http://jsfiddle.net/faG4J/4/ that shows the logging output. I’m probably doing something really stupid, so any help would be most appreciated.
Those variables which you set are not properties of your module – they’re just local variables. You have exported their values to the module object, but at a time they weren’t set.
However, this is not the way you should do it at all. Don’t make a promise for some properties of some object being set, but make a promise for these values.
As modules with only one function seem quite useless to me, I’ve omitted them here:
Then use something like
getPosition.done(createMap).