use paging with ajax call in a while loop - javascript

In a javascript function I make a call to the server and get batches of 10 records back. I need to do this untill I've had all records.
To start I made a while loop where in the error callback of the ajax call I would end the while loop.
Halfway through I started to realize that that would not work, as the ajax call is async and I would thus fire loads of requests in the loop. I'm sure there is a standard pattern to do this but I don't know how.
How can I do the ajax call in a loop and perform it as long as the call is not returning an error?
Pseudo code I was building:
var stillRecordsAvailable = true;
while (stillRecordsAvailable) {
// get the next batch of records
$.ajax({
url: '/getrecords.json',
data: {data_set_id: dataset.id},
type: 'GET',
success: function(data, textStatus, xhr) {
// do something
},
error: function(xhr, textStatus, errorThrown) {
// nothing left to do
stillRecordsAvailable = false;
}
});
Thanks for pointing me in the right direction

You'd probably want to just wrap the ajax call in a function that is called on the ajax success callback:
function getRecords(data, textStatus, xhr) {
if (data) {}; // do something...
$.ajax({
url: '/getrecords.json',
data: {data_set_id: dataset.id},
type: 'GET',
success: getRecords
});
}
This will only work if your server/API returns an error when no more records exist; however, this may not be the best pattern. A more elegant way of tracking asynchronous event state is through a deferred/promise pattern. jQuery has a great implementation: http://api.jquery.com/category/deferred-object/

Related

Ajax hits success callback before backend call finishes?

I'm running into the following issue:
an ajax call goes out to a backend jsp call
sometimes(?) the success() callback on the ajax call is hit before the backend call finishes
I didn't think this was possible :)
The code looks something like this:
var opt = {
form: $form,
retry: '0',
retryHandler: function(...) { alert(...);},
dataType: 'xml',
url: url,
error: function(xhr, status, e) { ... }
timers: {},
timeout: timingConfig.timeout,
beforeSend: function(xhr) { ... },
success: function(data, status, xhr) {
// breakpoint in here
}
One breakpoint in success callback, and one breakpoint in the backend jsp.
Both are hit at roughly the same time, where I'd expect success() to not be called until the the backend call finishes.
Any ideas on what's going on here? O_o

Syncronous AJAX stops on Error

I do have AJAX request and in the success callback new function to rendergooglelinks and another AJAX calls are called.
And now, I try to change the asyncronous calls to syncronous using async: false in the AJAX request.
When I do a AJAX request, rendergooglelinks are not rendered due to "undefined" error and next ajax request works.
In the syncronous ajax request, progress stops after rendergooglelinks error. Next calls are not triggered.
(i.e) Codes after that error are not processed.
Whether syncronous ajax request stops on errors ?
Whether it behaves in the way of "strict" mode ?
How can we handle this ?
// syncronous request
$.ajax({
type:"GET",
async: false,
url: url,
success: function(result, status, xhr) {
rendergooglelinks();
renderComments(); // this is not called due to error in the above
}
});
function rendergooglelinks()
{
google.test = ''; // returns error
}
function renderComments()
{
// asyncronous request
$.ajax({
type:"GET",
url: url,
success: function(result, status, xhr) {
}
}
});
Based on the code you posted, the error is that the variable google is never declared, so google.test cannot be assigned.
On the other hand, synchronous ajax calls are not a good practice, avoid them if possible.
Last but not last from jQuery.ajax() docs:
Deprecation Notice: The jqXHR.success(), jqXHR.error(), and jqXHR.complete() callbacks are removed as of jQuery 3.0. You can use jqXHR.done(), jqXHR.fail(), and jqXHR.always() instead.
For the google variable, i suggest you to pass it to the function as argument, is dangerous to assume that it exist no matter what.
For other errors, try this:
$.ajax({
type:"GET",
//async: false,
url: url,
/*success: function(result, status, xhr) {
rendergooglelinks();
renderComments(); // this is not called due to error in the above
}*/
}).then([ //success callbacks
rendergooglelinks,
renderComments
],[
//no fail callbacks
]);
function rendergooglelinks(){
google.test = ''; // returns error
}
function renderComments(){
// asyncronous request
$.ajax({
type:"GET"
url: url,
/*success: function(result, status, xhr) {
}*/
}).done(function(result, status, xhr){
});
}
See also jQuery Deferred

How to call code-behind method from 'success' in ajax callback?

How to modify below code to use 'success' to call testMethod() in code-behind ?
I need to wait for return value from testMesthod() and process it.
$.ajax( {
url : 'myPage.aspx/testMethod',
type : "POST",
contentType : "application/json; charset=utf-8",
data : "{'name':'" + aNb + "'}",
dataType : "json"
}).done(function() {
alert("ok");
}).fail(function() {
alert("not ok");
});
Above code does not work because somehow latest JQuery version (1.10.1) gets overwritten by 1.3.2.
Thank you
You would need to pass the callback function to the function that wraps your $(ajax).
function getData(ajaxQuery, callBack){
var ajaxHREF = 'your url';
$.ajax({
url: ajaxHREF,
type: "post",
data: ajaxQuery,
beforeSend: function ( xhr ) {
xhr.overrideMimeType("application/json");
},
success: function(response, textStatus, jqXHR){
var jsonData = $.parseJSON(response);
callBack (jsonData);
},
However, a much better way of doing this is the global success event. It is better because you have all of the properties of the call available to you to enable dynamic processing of the results. Create the global success event inline = $(document).ajaxSuccess this gets called for all jquery ajax success events so you need to differentiate which calls apply to your specific handler (to each global handler).
$(document).ajaxSuccess(function(event, xhr, settings) {
var query = settings.data;
var mimeType = settings.mimeType;
if (query.match(/ameaningfulvalueforthishandler/)){
if(mimeType.match(/application\/json/)){
var jsonData = $.parseJSON(xhr.responseText);
}
}
}
Thank for replies, but I still do not see how callbacl can help me.
I need to call webmethod in code-behind: testMethod()
Ajax call does it, url = "myPage.aspx/testMethod" will 'call' webmethod testMethod(),
but it's asynchronous and returns quickly into 'success' section of ajax call.
But, I need to Wait for testMethod() to finish processing, retrieve result returned by testMethod() and process it.
Asynchronous ajax will return us into 'success' without waiting for testMethod() to finish,
and we will not get any data in response.
So, how callback helps me to achieve it?
function getData(ajaxQuery, callBack){
var ajaxHREF = "myPage.aspx/testMethod";
$.ajax({
url: ajaxHREF,
type: "post",
data: ajaxQuery,
beforeSend: function ( xhr ) {
xhr.overrideMimeType("application/json");
},
success: function(response, textStatus, jqXHR){
var jsonData = $.parseJSON(response);
callBack (jsonData);
});
Thank you
#Karen Slon - If I understand the question correctly, I think you need to conceptually separate the client side from the server side. The callback in .success/.done or global ajaxSuccess event enable your web page to initiate the request and keep on processing while the server side is processing your request 'myPage.aspx/testMethod'. When it completes successfully it returns to the success event. Now if testMethod does not return anything then you will find yourself in the success event event without a result. But you cannot get there unless web method testMethod has completed successfully and returned control. The .done event in your example only has alert("ok");. What makes you believe that the web method testMethod is not complete when the .done event occurs?
Look at these posts for better examples:
jQuery.ajax handling continue responses: "success:" vs ".done"?
http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/
http://api.jquery.com/category/deferred-object/

Delay between repeated AJAX call to a web method

I have a ASP.Net web app with jquery implemented on the client side. within a while loop, the client side jquery script makes an asynchronous call to a web method in the server side code. The call returns the status of a long running server side task which jquery uses to update the user. The goal is to have jquery repeatedly call the server until the status is complete, once done it breaks out of the while loop and notifies the user thatthe task is complete.
My problem is that the below code runs in a while loop, but I want to make it delay or sleep between each call in order to prevent overwhelming the server with status requests. I tried calling setTimeout in the code below, but it only works with the initial ajax call, every subsequent call occurs back to back. Is there a way to efficiently delay each subsequent call to the server? Is this the most efficient way to achieve the kind of behavior I'm describing? Ideally I'd like a 2-5 second delay between each call.
I have the following code
Client Jquery:
var alertTimerId;
$('input[name=btnStatus]').click(function () {
var result = false;
//Loop while server reports task complete is true
while (!result) {
alertTimerId = setTimeout(function () {
$.ajax({
type: "POST",
url: "Default.aspx/GetStatus",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function (msg) {
if(msg.d != false)
result = msg.d;
},
error: function (xhr, ajaxOptions, thrownError) {
alert('AJAX failure');
}
});
}, 2000);
if (count > 0) {
count--;
}
}
});
Server Side ASP
[System.Web.Services.WebMethod]
public static bool GetStatus()
{
return result;
}
How about something like the following? The idea is that the Ajax call is encapsulated in a function, doAjax(), and then from within the Ajax success handler if the result is false you use setTimeout() to queue up another call to doAjax, otherwise you take whatever action you want to take for a true result. (You could optionally call doAjax() from the Ajax error handler too.)
$('input[name=btnStatus]').click(function () {
function doAjax() {
$.ajax({
type: "POST",
url: "Default.aspx/GetStatus",
data: "{}",
contentType: "application/json; charset=utf-8",
dataType: "json",
async: true,
success: function (msg) {
if (!msg.d)
setTimeout(doAjax, 2000);
else {
// Success! Notify user here
}
},
error: function (xhr, ajaxOptions, thrownError) {
alert('AJAX failure');
}
});
}
doAjax();
});
(Note: I've removed the if statement with count, since it seemed to have no relevance to the question. If your real code uses it just update it within the Ajax success handler too.)
Underscore.Js has a .throttle() helper function:
throttle_.throttle(function, wait)
Creates and returns a new, throttled version of the passed function, that, when invoked
repeatedly, will only actually call the original function at most once
per every wait milliseconds. Useful for rate-limiting events that
occur faster than you can keep up with.
var throttled = _.throttle(updatePosition, 100);
$(window).scroll(throttled);

jQuery $.ajax call works in Chrome, but not any other browser

The following call works perfectly in Chrome, but fails in every other browser.
function getInfo(r,c,f){
return $.parseJSON($.ajax({
url: baseURL + 'somethingAPI/getInfo',
data: {
"data_r": r,
"data_c": c,
"data_f": f
},
//success: function(data){},
dataType: "json",
async: FALSE
}).response);
}
Yes, I'm using a synchronous ajax call and I believe it is necessary as I don't want any of the other JS to run without this executing and returning data. Although, I'm not entirely sure if something else should be happening with the success callback.
Anyway, in Chrome I get the response object (JSON) and can access the data within just fine.
Does anyone know what I'm doing wrong?
Regarding your point about not knowing how to avoid async: false, is this something like what you're looking to accomplish?
function getInfo(r, c, f, callback) {
$.ajax({
url: baseURL + 'somethingAPI/getInfo',
data: {
"data_r": r,
"data_c": c,
"data_f": f
},
dataType: "json",
success: callback,
});
}
getInfo('foo', 'bar', 'baz', function(response) {
console.log(response);
});
Rather than parsingJson on the ajax query, here's the syntax I use to conquer these challenges
$.ajax({
url: "pagegoeshere.php",
timeout: 30000,
type: "POST",
data: 'data1='+data1+'&data2='+data2,
dataType: 'json',
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert("An error has occurred making the request: " + errorThrown)
},
success: function(returnjson){
var returnstuff = returnjson.returnstuff;
//Do next Javascript step here
}
});
You can run ensuing javascript/jquery in the success and "stack" events together on success of your Ajax call. That way, if it works, it proceeds. Otherwise, the error handling can occur in the provided error section in a manner that you define. I generally fire my ajax calls on a click handler, but it's certainly doable to run it in a function as you have chosen. Be sure to check your return JSON (could be mailed from your processing page, for example) to make sure it's valid JSON. Jsonlint is your friend!
I've had chrome effectively parse bad HTML and JSON while the other browsers don't on several occasions. I'd suspect it's something along those lines that's specifically causing your issues.

Categories

Resources