OK, so json.length exists and is always 30. Not what I was expecting but let's assume that json, for whatever reason, is an array.
First try replacing the ajax block in fetchMarkersInfo with,
this.ajaxConnPopup = $.ajax({url: URL_API,
data: params,
type: "POST",
dataType: 'json',
success: function(json){
if(!json || !json.length) { return; }
obj.markersInfo = obj.markersInfo.concat(json);
obj.markersInfoCompleted = true;
}
});
This should fetch your 30 random markers and unconditionally raise the flag so they won't be fetched again. This may or may not work. It should at least prevent repeated fetching of markers.
****
My only concern is that back in fetch, the bulk of the code may (I don't know for sure for sure) be dependent on the markers having been fetched, which will not be the case, at least the first time that fetch is called; reason being that the ajax is asynchronous - in other words fetchMarkersInfo will not be truly complete when fetch gets to the line this.clearOverlays(); .
If this is the case, then everything in fetch from this.clearOverlays(); onward needs to be made into a callback function for execution at the end of fetchMarkersInfo's ajax success fn. (It's possible that the original programmer didn't know this technique and needed to jump through several awkward hoops as a workaround).
Follow me? Probably not unless you are familiar with asychronicity and callbacks.
Anyway, the upshot would be a refactoring of fetch and fetchMarkersInfo as follows:
fetch: function(zoom){
if(!this.gmap) return ;
var obj = this;
this.clearPopup();
var callbackFn = function(){//define a callback for execution when fetchMarkersInfo has completed.
this.clearOverlays();
var category = this.selectedCategories();
var params = 'q=cluster&'+ this.fetchBounds2Param(this.fetchBound())+'&zoom='+this.gmap.getZoom()+(this.gmap.getZoom() == this.gmap.maxZoom? '&markers=1' : '')+(category == '' ? '' : '&cat=' +escape(category));
if(this.ajaxConn){
this.ajaxConn.abort();
this.ajaxConn = null;
}
this.enableGMap(false);
this.ajaxConn = $.ajax({
url: URL_API,
data: params,
type: "POST",
dataType: 'json',
success: function(json){
obj.showResults(json);
},
complete: function(jqXHR, textStatus){
obj.enableGMap(true);
if(obj.popupActive) { return; }
obj.popupActive = true;
if(obj.popupTimeout) { clearTimeout(obj.popupTimeout); }
obj.popupTimeout = setTimeout(Clusters.popupNext, POPUP_DELAY);
}
});
};
this.fetchMarkersInfo(callbackFn);//callbackFn will be executed when fetchMarkersInfo's ajax has completed.
},
fetchMarkersInfo: function(callbackFn){
callbackFn = (!callbackFn) ? function(){} : callbackFn;//in case fetchMarkersInfo is called without a callbackFn
if(!this.gmap) return ;
if(this.markersInfoCompleted){ callbackFn(); }//in case fetch fires again after markersIno has been fetched
else{
var lastId = (this.markersInfo.length > 0 ? this.markersInfo[this.markersInfo.length-1].id+1 : 1);
var category = this.selectedCategories();
var obj = this;
var params = 'q=list&from='+ lastId+ '&'+ this.fetchBounds2Param(this.fetchBound())+(category == '' ? '' : '&cat=' +escape(category))+'&lmt=30';
if(this.ajaxConnPopup){
this.ajaxConnPopup.abort();
this.ajaxConnPopup = null;
}
this.ajaxConnPopup = $.ajax({url: URL_API,
data: params,
type: "POST",
dataType: 'json',
success: function(json){
if(!json || !json.length) { return; }
obj.markersInfo = obj.markersInfo.concat(json);
obj.markersInfoCompleted = true;
callbackFn();
}
});
}
},
You will appreciate, I'm working half blind here as I can't actually run the code and my suggestions may need debugging.Airshow