I am trying to get a response from a web service, specifically to add two WFS layers from geoserver to a leaflet web map. The first layer gets added no problem every time, but most of the time, the second layer fails, complaining that the callback function is not defined:
ReferenceError: getJson is not defined
But what is very strange to me is that the second layer will be added, only sometimes. Refreshing the page and trying again will almost always fail.
This is the code making the ajax call:
$(document).ready(function() {
...
$("#add-network-button").on("click", function() {setLocation("Moscow")})
function setLocation(locationName) {
var networkParameters = {
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: 'netex:' + locationData[locationName].networkWFSName,
maxFeatures: 99999,
outputFormat: 'text/javascript',
format_options: 'callback: getJson'
};
addWebService(map, WFSURL, networkParameters)
var buildingParameters = {
service: 'WFS',
version: '1.0.0',
request: 'GetFeature',
typeName: 'netex:' + locationData[locationName].buildingWFSName,
maxFeatures: 99999,
outputFormat: 'text/javascript',
format_options: 'callback: getJson'
};
addWebService(map, WFSURL, buildingParameters)
}
And here is the addWebService
function:
var addWebService = function(map, WFSURL, WFSParameters) {
var leafletWFSParameters = L.Util.extend(WFSParameters);
console.log(WFSURL + L.Util.getParamString(leafletWFSParameters));
$.ajax({
url: WFSURL + L.Util.getParamString(leafletWFSParameters),
dataType: 'jsonp',
jsonpCallback: 'getJson',
success: handleJson,
cache: false
});
// TODO: add style
function handleJson(data) {
L.geoJson(data, {}).addTo(map);
}
}
You're using jsonp
, which means the data you're getting back is not JSON, but javascript code that makes a call to a globally-defined function (which name is defined by jsonpCallback
).
jQuery automagically creates a function with that name, performs the network request, and when that function runs, it destroys its own reference from the global scope.
You're performing two calls to addWebService()
in quick succession, which trigger two jQuery $.ajax({jsonpCallback: 'getJson'})
calls. The second call is overwriting the globally-defined getJson
callback function. When the first jsonp payload is received by your browser, the globally-defined getJson
callback is destroyed. When the second jsonp payload is received, it tries to call a globally-defined getJson
function, and failing. A classic race condition.
Let me quote jQuery's documentation for the jsonpCallback
parameter on $.ajax()
, empasis mine:
jsonpCallback
Type: String or Function()
Specify the callback function name for a JSONP request. This value will be used instead of the random name automatically generated by jQuery. It is preferable to let jQuery generate a unique name as it'll make it easier to manage the requests and provide callbacks and error handling. You may want to specify the callback when you want to enable better browser caching of GET requests.
I suggest you either use other transport format than JSONP, or use different callback names for each request.