jQuery AJAX polling for JSON response, handling based on AJAX result or JSON content

Bungle picture Bungle · Sep 10, 2009 · Viewed 41.9k times · Source

I'm a novice-to-intermediate JavaScript/jQuery programmer, so concrete/executable examples would be very much appreciated.

My project requires using AJAX to poll a URL that returns JSON containing either content to be added to the DOM, or a message { "status" : "pending" } that indicates that the backend is still working on generating a JSON response with the content. The idea is that the first request to the URL triggers the backend to start building a JSON response (which is then cached), and subsequent calls check to see if this JSON is ready (in which case it's provided).

In my script, I need to poll this URL at 15-second intervals up to 1:30 mins., and do the following:

  • If the AJAX request results in an error, terminate the script.
  • If the AJAX request results in success, and the JSON content contains { "status" : "pending" }, continue polling.
  • If the AJAX request results in success, and the JSON content contains usable content (i.e. any valid response other than { "status" : "pending" }), then display that content, stop polling and terminate the script.

I've tried a few approaches with limited success, but I get the sense that they're all messier than they need to be. Here's a skeletal function I've used with success to make a single AJAX request at a time, which does its job if I get usable content from the JSON response:

// make the AJAX request
function ajax_request() {
  $.ajax({
    url: JSON_URL, // JSON_URL is a global variable
    dataType: 'json',
    error: function(xhr_data) {
      // terminate the script
    },
    success: function(xhr_data) {
      if (xhr_data.status == 'pending') {
        // continue polling
      } else {
        success(xhr_data);
      }
    },
    contentType: 'application/json'
  });
}

However, this function currently does nothing unless it receives a valid JSON response containing usable content.

I'm not sure what to do on the lines that are just comments. I suspect that another function should handle the polling, and call ajax_request() as needed, but I don't know the most elegant way for ajax_request() to communicate its results back to the polling function so that it can respond appropriately.

Any help is very much appreciated! Please let me know if I can provide any more information. Thanks!

Answer

Joel picture Joel · Sep 10, 2009

You could use a simple timeout to recursively call ajax_request.

success: function(xhr_data) {
  console.log(xhr_data);
  if (xhr_data.status == 'pending') {
    setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
  } else {
    success(xhr_data);
  }
}

Stick a counter check around that line and you've got a max number of polls.

if (xhr_data.status == 'pending') {
  if (cnt < 6) {
    cnt++;
    setTimeout(function() { ajax_request(); }, 15000); // wait 15 seconds than call ajax request again
  }
}

You don't need to do anything in your error function unless you want to put an alert up or something. the simple fact that it error will prevent the success function from being called and possibly triggering another poll.