Drupal Ajax data retrieval delayed - ajax

I have a simple click function with the code below, but I can't seem to get the data on the first click.
$.ajax({
type: 'POST',
url: 'test/get/1',
success: function (result) { testit = result; },
dataType: 'json',
data: 'js=1'
});
alert(testit);
In my callback function I simply have return drupal_json('hello'); but it doesn't show up until the 2nd time around. For example, if I click the button, nothing will happen, but if I click it again, it will alert 'hello'. In a case where there is dynamic data, then it will also be delayed by one click. For example, let's say clicking the first time should alert 1, 2nd time should alert 2, and so on. Instead, the first click will do nothing, the 2nd click will alert 1, the 3rd click will alert 2, etc. Any ideas why that is happening? Thanks.

the a in ajax stands for asynchronous. therefore, testit will not be set to the result of the ajax's response until the success: function is called (when the ajax call is successfully completed)
$.ajax({
type: 'POST',
url: 'test/get/1',
success: function (result) { testit = result; alert(testit); },
dataType: 'json',
data: 'js=1'
});
if you'd like it to work synchronously, you can also set aysnc:false in jQuery's .ajax options, like so:
var testit = $.ajax({
type: 'POST',
async: false,
url: 'test/get/1',
dataType: 'json',
data: 'js=1'
}).responseText;
alert(testit);
in the second method, ALL javascript will be delayed until the ajax call is complete (usually noticeably slow). I'd recommend just doing your code in the success: callback from the first example. however, you may want to create an error: callback, too, just in case something fails (otherwise your callback may NEVER get called, because there was no success).

This is probably happening because the AJAX request doesn't block the script. It goes ahead and makes the request, but doesn't wait for the results to come back before it executes the next line (your alert). Thus the first time it hits the alert no data has been fetched, the second time it only has the data from the first request (the second request has started, but not finished), and so on.
The solution is to put the alert in your callback function, which doesn't get executed until after the response has been received:
$.ajax({
type: 'POST',
url: 'test/get/1',
success: function (result) { alert(result); },
dataType: 'json',
data: 'js=1'
});

Related

Caching Ajax response

I am trying to cache the result of a JQuery. This is my Ajax call:
$.ajax({
dataType: "json",
url: myEndPoint,
type:"GET",
cache:true,
startTime: performance.now(),
data: {"query": myQuery,
"output": "json"},
success: createDisplay,
error: myError
});
console.log('After .ajax');
};
I am trying to do this so that I minimize the amount of Ajax calls as I noticed that it takes about 2.4s to get the results which results in a lag time on the web user interface. In the networks console window I can see that the query is being re-executed even if it has been performed before. What am I doing wrong? Can I see the cached contents anywhere?
Sure you can store it on localStorage.
There is also a library that does just that: cache4.js
It is a wrapper for the jQuery ajax call. Just pass to it what you would pass to $.ajax.
[EDIT] Sure Simas Joneliunas Although I can guarantee that the docs will stay the same, as I own the repository.
Using the question example, it would be something like this:
cache4js.ajaxCache({
dataType: "json",
url: myEndPoint,
context: {
startTime: performance.now()
}
data: {
"query": myQuery,
"output": "json"
},
success: createDisplay,
error: myError
}).then(function (res){
console.log('After .ajax');
});

How do I use data passed back in the response from ajax jQuery?

I am trying to use the response from a jQuery ajax request to set the innerHTML of a div with a certain id. This is the code I am using:
$(".show_comments").click(function(){
var articleName = $(this).closest("article").find(".articlename").attr('id')
$.ajax({
url: "commentView.php",
data: { 'articleName': articleName },
cache: false,
dataType: "html", // so that it will auto parse it as html
success: function(response){
$(this).closest("article").find(".comments").html(response);
}
});
however it doesn't seem to be doing anything at all, I've tried googling around, but everything I can find says to do it the way I am doing it... I have tested in Firebug and the ajax request is giving me the exact response I want it too... But I just cant access this to set the innerHTML of the div to the response!
In your ajax success handler there is another scope and this points to not what you think. So change your code to:
var articleName = $(this).closest("article").find(".articlename").attr('id'),
that = this;
$.ajax({
url: "commentView.php",
data: { 'articleName': articleName },
cache: false,
dataType: "html", // so that it will auto parse it as html
success: function(response){
$(that).closest("article").find(".comments").html(response);
}
});
What I've changed: I added that variable that points to this instance and use it in the success handler instead.
How would you debug it yourself: if you tried to output console.log(this) and console.log($(this).closest("article").find(".comments")); you would see that it returns a wrong object (in first case) and nothing in second.

2 concurring ajax request one slow, one quick, both end in the same time

I have to query (via Ajax) 2 scripts at the same time.
I know for sure that one is really quick, it just displays some html, the second is doing some query using a WebService.
The quick request, is always sent after the first one. But with all my attempts, the fast/quick one, never completes before the slow one.
The code use to call the first long ajax request:
$.ajax({
type: "POST",
url: '/fr/ajax_flight_get_other_oneway',
cache: false,
dataType: 'json',
success: function(data) {
// some treatment
}
The code for the second faster ajax request:
$.ajax({
type: "POST",
url: '/fr/load_back_forflight?id=SN4422_23',
cache: false,
data: "comps="+compSelectedCodes+"&escale="+escale,
dataType: 'json',
success: function(data) {
// some treatment
}
Is it something in Apache that should be changed or is it in jQuery?
I found the solution to my problem, it was linked to the session.
the session was based on file system. So the first (long query) is lock the session file, and then the second one is forced to wait for the long query to finish.
by using session in DB, I've resolved the problem.
thanks for your help
Put the slow one in the success callback of the fast one. This will guarantee that the fast request will finish first before starting the second request.
It's possible that the browser decided to use the same HTTP connection for both (using the HTTP header Keep-alive) and thus it appears queued. This is not a jQuery thing -- it's something that browsers can opt to do.
Use your browser's HTTP network traffic debugger to see if that's the case.
If not, then your web-server may be only allowing one connection per client and is queueing them. See this:
How do I configure Apache2 to allow multiple simultaneous connections from same IP address?
Try this:
$.ajax({
type: "POST",
url: '/fr/ajax_flight_get_other_oneway',
cache: false,
dataType: 'json',
success: function(data) {
// some treatment
//The code for the second faster ajax request:
$.ajax({
type: "POST",
url: '/fr/load_back_forflight?id=SN4422_23',
cache: false,
data: "comps=" + compSelectedCodes + "&escale=" + escale,
dataType: 'json',
success: function(data) {
// some treatment
}
});
}
});​

jQuery ajax event success handling

I have the following code multiple times:
$.ajax({
type: "POST",
cache: false,
url: "url here",
success: function (data) {
// do something here...
}
});
I'd like to turn this into a function as use it only once, somthing like:
function ajax (type, url, complete){
$.ajax({
type: type,
cache: false,
url: url,
success: function (data) {
GO TO THE METHOD SPECIFIED IN complete
}
});
How would I run a method specified in the complete variable? Is it possible? I've looked at the ajax success event for jQuery but since it would be triggered on every item that uses it, I would then have to check if it is the correct ajax request...
If complete is a reference to a function,
function ajax (type, url, complete){
$.ajax({
type: type,
cache: false,
url: url,
success: complete
});
Just make sure complete's arguments match what is given by success.
EDIT: If complete is an object, just find the function on it and use that:
success: complete.foo
Hope this is what you're asking...
If understand question correctly
function ajax (type, data, url, complete){
$.ajax({
type: type,
data:data,
cache: false,
url: url,
success: complete
});
}
var obj={ id:1}
/* example case use */
ajax ('POST', obj 'site.com', myAjaxComplete);
/* a success callback from ajax*/
function myAjaxComplete(data){
// data argument is return data from server
}
EDIT: you'll definitely want to add an argument for data to send to server

Chrome jquery ajax callback on success not firing

As far as I know, $.ajax has always worked pretty smoothly in every browser until now.
I have a pretty simple function, called when a couple of actions from the user occur.
In Firefox, everything runs smoothly. But in Chrome, while the $.ajax request is launched, the callback on success doesn't fire.
Here's the actual snippet:
var form = $("#templateCreator"),
formType = form.attr("method"),
formData = form.serialize(),
action = form.attr('action');
$.ajax({
type: formType,
url: action,
data: formData,
success: function(){
console.log('Can\'t see me in Chrome, but ok in firefox !')
// Handle all form submit events to form validator first
validator(form, targetInput);
}
});
What's puzzling is nothing seems wrong, data is serialized, and sent properly. Does anyone know what I missed?
Start by adding an error and complete method as #Jasper suggested.
$.ajax({
type: formType,
url: action,
data: formData,
success: function(){
console.log('Can\'t see me in Chrome, but ok in firefox !')
// Handle all form submit events to form validator first
validator(form, targetInput);
},
error: function() {
console.log($.makeArray(arguments));
},
complete: function() {
console.log($.makeArray(arguments));
}
});
Then you can:
open Chrome debugger (F12), go to the scripts tag, and put a breakpoint inside success/complete/error; check out the stack trace and values for an epiphany ;)
have a look at the console logs
For great joy, take off every Zig!
I had this issue, and set async: false. This works for me in Chrome. Looks like Chrome has an issue with async: true.
restget = function(url, cb){
$.ajax({
url: url,
dataType: 'json',
crossDomain: true,
async: false,
success: cb
});
Try this .....
data: formData,
async: false,
Chrome has some issues with async calls.
I had a similar problem while trying to get a json array. I had to add dataType: 'json' to my ajax so that non-Firefox browsers know what my data type is. For instance:
$.ajax({
type: 'Get',
url: "http://api.geonames.org/earthquakesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&username=demo",
success: function(data){
var jsonArray = jQuery.parseJSON(data);
alert(jsonArray.status.message);
}
});
and
$.ajax({
type: 'Get',
url: "http://api.geonames.org/earthquakesJSON?north=44.1&south=-9.9&east=-22.4&west=55.2&username=demo",
dataType: 'json',
success: function(data){
var jsonArray = data;
alert(jsonArray.status.message);
}
});
will display the same thing when ran in Firefox firebug. But when you run this in Chrome DevTools it will only work on the bottom one. I hope this fixes your problem.

Resources