2nd AJAX call to same URL fails - but works randomly and rarely - ajax

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.

Related

Asynchronously populate Sammy.Storage cache

I'm having difficulty accessing requestJSON on a jQuery $.ajax object outside of the success callback. If I do:
var ajax_request = $.ajax({
dataType: 'json',
contentType: 'application/json'
});
console.log(ajax_request.responseJSON);
// this results in `undefined`
How can I access the responseJSON without adding a .success() callback? If I inspect ajax_request in Firebug, I can see the responseJSON property, and the data I expect, but I can't access it via:
ajax_request.responseJSON
More specifically, I'm building an SPA using Sammy and Knockout. In some routes, I need to be able to get JSON from cache, and if it doesn't exist, get the value from a service call and then set it into cache:
var cached_json = storage.fetch('cached_json', function() {
// make service call
return $.getJSON(url);
});
event_context.render('template.tpl', {'json': cached_json}).appendTo('#my-target');
But, of course, calling storage.fetch doesn't cause the rest of the code to pause until $.getJSON is complete. This is the part I can't quite figure out how to structure.
here's how i would implement it
responseJSON = "";
$.get("myurl.php",function(jdata){
responseJSON = jdata;
},"json");
i like to see the ajax method at a glace, but in your case you can do the same by
....
success : function(jdata){ responseJSON = jdata; }
....
PS: i believe that initializing the blank responseJSON is not required since any variable without var is in global scope, but it would help for clarity
I ended up solving this by creating a deferred object that gets or creates the value I need:
function get_or_create_cache(storage, key, service_endpoint) {
return $.Deferred(function(deferred) {
var c = storage.get(key);
if (c === null || c === undefined) {
$.when(jsonp_service_request(service_endpoint)).done(function(json) {
storage.set(key, json);
deferred.resolve(json);
});
}
else {
deferred.resolve(c);
}
}).promise();
}
In this function, storage refers to a Sammy.Storage instance. jsonp_service_request is a local function that returns a jsonp response, taking into account the location.hostname for local development, where I'm pointing to local.json files, or a remote environment, where I'm calling into an actual API. jsonp_service_request returns an $.ajax function.
Then in my Sammy route, I can do:
this.get('#/', function(event_context) {
$.when(get_or_create_cache(storage, 'my-cache-key', 'service-endpoint'))
.then(function(json) {
event_context.render('my-template.template', {'value-name': json})
.appendTo('#my-target');
});
});

Ajax Request success vars scope

I have a function in the success of a Ext.Ajax.request. I need that this function returns a variable with a JSON Store.
My code is:
gridplatos.getStore().each(function(r){
var store;
Ext.Ajax.request({
params:{
grado: r.get('grado'),
menudiario: r.get('menudiario'),
plato: r.get('plato'),
transCode: Ext.getCmp('transCode').getValue()
},
url: 'src/Drivers/AlumnosPlatoArmado/',
method: 'GET',
success: function(response,store){
store = Ext.create('KMA.store.AlumnosPlatoArmado',{}).load();
}
});
console.log(store);
}
But, console.log(store) return "undefined". Any idea ?
It is because ajax is a asynchronous function call, means once the request is sent to the server the client will continue execution of following statements without waiting for the server response.
In your case the ajax request is sent to src/Drivers/AlumnosPlatoArmado/ then before the server response back console.log(store); is executed at that point of time store has the value undefined. Once the ajax request is completed successfully, the registered success handler will get called, where you are setting the value of store.
In a async execution environment all actions on values returned by the async method must be performed with in the registered callback methods only.

caching issue with jQuery/AJAX

I am getting data through $.ajax multiple times. However the data is not getting refreshed in every call. Rather I am getting the same data in every call to $.ajax. The code was working properly at my home.
However in below code if I substitute console.log("success "); with console.log("success "+data); and observe in chrome console, then the code works fine. I suspect its a caching issue, but can figure it out.
function getDataJSON()
{
originalData="";
new Date().toString();
$.ajax({
url: 'data.php', //the script to call to get data
data: "", //you can insert url argumnets here to pass to api.php
success: function(data)
{
console.log("success ");
...
...
Thanks
you can set cache Cache. by default it will set to cache=true.
from DOCS
If set to false, it will force requested pages not to be cached by the
browser. Note: Setting cache to false will only work correctly with
HEAD and GET requests. It works by appending "_={timestamp}" to the
GET parameters. The parameter is not needed for other types of
requests, except in IE8 when a POST is made to a URL that has already
been requested by a GET.
$.ajax({
url:'url',
cache:false,
.....
})
Like #Ravi said cache priperty is you're frined.
You should realy spend more time on studying you're weapon of choice!
Link => first hit on google if you search jquery ajax
There is another method of preventing caching. Just append some random number to url you are accessing.
For example:
"www.url.com?" + new Date().getTime()
or
"www.url.com?" + Math.random()
from Stack answer

request.html in local file gets status = 0

I'm making a functional mockup using mootools,and in this prototype I have to load an html file via request.HTML, but as soon as I run the script, the call never reaches the onSuccess due to the state = 0.
The blame could be that the request is treated as a violation of the crossdomain.
So I was wondering if is out there a way to work it around?
this is the code I use for performing the request
req = new Request.HTML({
url: "detail.html",
onFailure: function(a) { console.log("iFailed: " + a); },
onSuccess: function(r3, rEls, rHTML, rJS) {
console.log("It worked!!");
},
onComplete: function() { console.log('completed'); }
}).send();
as I run this it always goes into the onFailure and in the onComplete without hitting the onSuccess.
I need this to work with safari, because the mock shall work on an iphone/ipad/ipod.
thx a ton
in the end I managed it bu injecting an iframe via js, instead of populating the div via ajax.
it's kind of lame and it sucks a lot, but at least it work and it's good for prototyping purposes.

jQuery ajax call does not launch callback when data type is 'script'

For example with jQuery 1.5.2 or smaller this code will log 'ololo' in FireBug console:
$.get(
'some_url',
{ data: 'some_data' },
function() {
console.log('ololo')
},
'script')
Same with .ajax (any type of request), .post
But with jQuery 1.6-1.6.1 the callback does nothing. However, the callback will be launched if data type is anything except 'script'. For example, 'json' or 'html.'
I have not been able to find something concerning this on http://api.jquery.com/jQuery.get/
I think the "script" datatype makes jquery behave like getScript() which
Load a JavaScript file from the server using a GET HTTP request, then
execute it.
To me that means that no callback will be called, as the script will be executed.

Resources