Search code examples
jqueryajaxpolling

Polling, Ajax and Status Callback


I want to continuously poll using jQuery and AJAX to a URL until I get a 200 status code response. The URL points to a REST API which provides a file. Ideally I'm getting other status codes on which I'll just call the URL again, and only when 200 is returned I'll leave the recursion and do something else.

For the recursion I need to preserve var jsonobj.

I fail miserably with getting the response out of the ajax call. I've tried to replicate this. Earlier I tried to get jsonobj processed in statusCode but it didn't traverse.

var jsonobj = 9189829182 // (job-id) returned from an earlier call which is not depicted here

function doPoll(jsonobj) {
  function pollQuery(p_data, state) {
    jQuery.ajax({
      headers: {
        "access-token": "67e9489669217"
      },
      type: 'GET',
      url: 'https://someurl/classifier/' + jsonobj["id"],
      crossDomain: true,
      statusCode: {
        200: function(p_data, state) {
          console.log("data available");
        },
        204: function(p_data, state) {
          console.log("processing");
        }, // this shows on console, but how do we get the state out of here?
        404: function(p_data, state) {
          console.log("resource not found / not available");
        }
      }
    })
  }

  console.log("jsonobj :" + jsonobj);

  pollQuery(function(response) {
    console.log("response :" + response); // not working
    console.log("state :" + state); // not working
  });
}

Solution

  • To fix this you need to correct the callback argument, as you're overriding it in each of the statusCode handler functions. In addition, you can simplify the logic by retrieving the status code from the jqXHR object passed to success instead of having to write code for every possible status code. This will also make the recursion more straightforward. Try this:

    function doPoll(obj) {
      function pollQuery(callback) {
        jQuery.ajax({
          headers: {
            "access-token": "67e9489669217"
          },
          type: 'GET',
          url: 'https://someurl/classifier/' + obj["id"],
          crossDomain: true,
          success: function(data, status, xhr) {
            if (xhr.status !== 200) {
              setTimeout(function() {
                pollQuery(callback); // recurse after 10 second delay
              }, 10000);
              
              // if required you can handle the messages shown for 204 and 404 states here...          
            } else {
              callback && callback(data); // 200 received, execute callback function
            }
          }
        })
      }
    
      pollQuery(function(response) {
        console.log("response :" + response);
      });
    }

    However I'd strongly suggest you do not follow the pattern of AJAX polling as it doesn't scale and, long term, causes more problems than it solves. I'd strongly suggest you follow the observer pattern for this instead by using Websockets. There are lots of resources available showing how to do this when you search.