0

I am using ajax to refresh a table on the page using the code below

true, :class => 'btn btn-success btn-xs ' %>

On the server the page reload starts a process to generate a big table. Currently I send from server a simple "Still processing" if big table not ready and if big table is ready then a large amount of html.

Q1. How to start periodic ajax refresh? Q2. How do I interpret the server result to stop the periodic ajax refresh?

shubham
  • 39
  • 1
  • 4
  • Way too little information given for a proper feedback - Please see http://stackoverflow.com/help/how-to-ask – wiesion Oct 08 '15 at 00:58

3 Answers3

1

Although @mb_s88's answer is the direct answer to your question (I even upvoted it), I would recommend that you re-think the workflow.

I would suggest that the AJAX response always return up to an X amount or data (i.e. up to 100 rows).

A better workflow will feel more responsive, the user could experience that "something is happening" (rather than just waiting) and you can avoid big blocking tasks on the server side by using smaller DB queries.

For example:

I would suggest that the first AJAX request will request the first "page" of the result and that a "continue" flag be set if the page is full (i.e., returning 100 rows would initiate a "continue" workflow).

Than I would recommend displaying the existing data while loading the next "page", each request asking the server for a specific page (i.e. for page numbers starting at 0 and row numbers starting at 0, asking for page_number=1 will return rows page_number * 100 to 100+(page_number * 100)).

An incomplete page (less than 100 rows) will stop the cycle.

As you can see, this design will use smaller SQL requests (requesting rows X to Y rather than the whole of the data), feel more responsive for the user and will allow the user to start reading through the data even as more data is coming in.

Myst
  • 18,516
  • 2
  • 45
  • 67
1

What you're asking is tricky for several reasons:

An AJAX request is a single user request. Unless you're employing multi-threading, sending multiple requests will not give you access to the same response, it's the equivalent of opening new requests each time you ping the server.

Unlike what most people think, Ajax isn't a magic lantern. It is simply a way for your browser to send & process XML requests (JSON) to/from your server. Indeed, Ajax itself stands for Asynchronous Javascript And XML:

enter image description here

Thus...


How to start periodic ajax refresh?

You don't.

There are two options you have:

  1. Ajax Long-Polling
  2. Ajax Callbacks

Long Polling is as mb_s88 described:

(function poll(){
   setTimeout(function(){
      $.ajax({ url: "server", success: function(data){
        //Update your dashboard gauge
        salesGauge.setValue(data.value);

        //Setup the next poll recursively
        poll();
      }, dataType: "json"});
  }, 30000);
})();

You send an Ajax request to the server every X seconds, appending responses to your DOM as necessary. This is typically used for extremely low-load instances (because you're sending constant requests to the server), in such things as chat applications, comments etc.

In short, long polling is the baby brother to web sockets. It's meant as a quick way to achieve near real-time functionality with JS. You'd use it to provide very low-level information, such as chat responses, notifications, etc.

The main limitation with Ajax is that it bombards your server with requests. This is bad, especially if you're dealing with a large amount of data.

--

The next option is to use ajax callbacks.

This is essentially where you wrap your Ajax response in a function, allowing you to process the asynchronous request synchronously. Sounds complicated? Not really, once you understand how Ajax works.

Ajax is meant to provide a way for you to send asynchronous requests to your server. This means that your requests will go around the standard browser flow.

enter image description here

This is a standard "synchronous" request, as is how all web browsers work.

The design is meant to be such that you'll receive a response for every request you send. For example, if you click a link, you're actually instructing the browser to send a request to the server, which it will pass a response to (in the form of a new web page).

AJAX gives you the ability to bypass this, adding the ability to send requests out of scope. The benefits of this would include the likes of - dynamic page updates, notifications, new information being applied on the page over-and-above the original request...

enter image description here

The problem with most Ajax functionality is the necessity to wait. Being asynchronous, there is no way for you to add it to the flow... in short, if you have dependent functionality, there's no way to "wait".

The way around this is to use a callback...

$(document).ready(function(){
   doAjax("url", {data: here}, function(){
       // Ajax "success" callback
   }, function(){
       // Ajax "error" callback
   });
});

doAjax(url, data, success, error){
    $.ajax({
       url: url,
       data: data,
       success: success(data),
       error: error(data)
    });
});

This gives you the ability to send an ajax request and "wait" for the response. This is opposed to setting "synchronous: true", which freezes the browser.


How do I interpret the server result to stop the periodic ajax refresh?

You use an Ajax callback and wait out the response.

If it's too big, split it into pages (as per @myst's answer).

If you still think you can ping your server and get multiple responses for the same request, read what I've written again. One request = One response.

Community
  • 1
  • 1
Richard Peck
  • 76,116
  • 9
  • 93
  • 147
0

In your script you can set the ajax request to go off every x milliseconds with a setInterval, and within the function executed by your timeOut you can have a conditional which cancels the timeout execution. That would look something like this:

intervalId = setInterval( function () {
    {{ Do your ajax thing, catch response in variable called data }}
    if (data.content !== "still processing") {
        doWhateverThingWithData(data);
        clearInterval(intervalId);
    }
}, 3000)

The 3000 at the end is the number of milliseconds between each execution.

edit: Accidentally used setTimeout and clearTimeout instead of setInterval and clearInterval

mb_s88
  • 392
  • 1
  • 12