Reputation: 179
I'm having a hard time understanding why this.$map
and this.markers
are undefined. Here's the code I'm working with and I have added comments where I expect these variables to supply a value:
(function($) {
'use strict';
var A = {
/**
* Initialize the A object
*/
init: function() {
this.$map = this.renderMap();
this.markers = this.getMarkers();
this.renderMarkers();
},
renderMap: function() {
var url = 'http://a.tiles.mapbox.com/v3/delewis.map-i3eukewg.jsonp';
// Get metadata about the map from MapBox
wax.tilejson(url, function(tilejson) {
var map = new L.Map('map', {zoomControl: false});
var ma = new L.LatLng(42.2625, -71.8028);
map.setView(ma, 8);
// Add MapBox Streets as a base layer
map.addLayer(new wax.leaf.connector(tilejson));
return function() {
return map;
};
});
},
renderMarkers: function() {
var geojsonLayer = new L.GeoJSON(null, {
pointToLayer: function (latlng){
return new L.CircleMarker(latlng, {
radius: 8,
fillColor: "#ff7800",
color: "#000",
weight: 1,
opacity: 1,
fillOpacity: 0.8
});
}
});
geojsonLayer.addGeoJSON(this.markers); // this.markers is undefined
this.$map.addLayer(geojsonLayer); // this.$map is undefined
},
getMarkers: function() {
$.getJSON("/geojson/", function (data) {
return data;
});
}
};
/**
* A interactions
*/
$(document).ready(function() {
A.init()
});
})(jQuery.noConflict());
I have spent much of the day searching and I think I'm missing something fundamental here, but I don't get it.
Upvotes: 0
Views: 308
Reputation: 28099
Neither the renderMap
, nor getMarkers
methods return any value, consequently their return value is undefined
.
It looks like you are trying to initialize these fields from an ajax request, which is not necessarily a good idea.
What you probably ought to do is something like:
getMarkers: function(callback){
var result = this;
$.getJSON("url", function(jsonData){
result.markers = jsonData;
if(callback) callback()
});
},
which will lazily initialize the fields of the object as they become available.
NB: AJAX is asynchronous you cannot rely on this callback setting the member quickly, or indeed ever (it could fail). This suggests you need to think a bit more about your design, and try to use callbacks more.
e.g. modify the getMarkers
and renderMap
functions as above to take a callback that is called after the data is stored then change init to:
init: function(){
var res = this;
var post_init_callback = function(){
if(res.$map != undefined && res.markers!=undefined){
//this will only run after both ajax calls are complete
res.renderMarkers();
}
};
this.getMarkers(post_init_callback);
this.renderMap(post_init_callback);
},
Upvotes: 3
Reputation: 12423
The problem here is that you call return inside another function. What you're essentially doing is defining getMarkers
(the simplest example) as this:
getMarkers: function() {
$.getJSON('/geojson/', some_random_func);
}
At which point it becomes obious that getMarkers doesn't actually return anything (ergo undefined). The same goes for your renderMap function. Also in this case your "some_random_func" is defined as function(data) { return data; }
but what does it return it to? Truth is that the some_random_func
is called by jQuery itself, and AFAIK jQuery doesn't care at all for the return-value of it's success-function.
Upvotes: 1