Search code examples
javascriptd3.jspromisexmlhttprequesttimeout

How to reject promise on d3 xhr request timeout?


I want to set a timeout value so that if the server does not respond in that particular time frame then UI should move ahead and not wait for response. I have used the below syntax so far but the UI gets hanged waiting for response. How can I specify a callback to reset the values and inform UI that no longer needed to wait.

q.promise(function(resolve, reject) {
  d3.xhr(my_url)
    .header('Content-Type', 'text/xml')
    .timeout(2000)
    .send(this.my_method, my_xmlData, function(error, data) {
    })
});

I read here that d3 xhr supports timeout feature now. How do I use that and execute a callback when request times out? Could anyone please tell me how to use that correctly? I tried using

.ontimeout(function(){console.log('request timedout!!'}) 

but it did not work.

I am using promises so I want to reject the promise in case of timeout. And I want to pass UI the same values it receives in case I receive error from service. Basically null values so that It settles down. But in case of timeout the UI does not receives any values and my screen loader keeps running.

TIA.


Solution

  • Since d3 v3 does not support time out, you can timeout like this:

    var url = "https://mysafeinfo.com/api/data?list=englishmonarchs&format=xml";
    let pr = new Promise(function(resolve, reject) {
      var xhr = new XMLHttpRequest();
      xhr.responseType = 'document';
      xhr.overrideMimeType('text/xml');
      xhr.open('GET', url, true);
      xhr.timeout = 1; // time in milliseconds
      xhr.onload = function(d) {
        console.log("load", xhr.responseXML)
        resolve(xhr.responseXML)
      };
    
      xhr.ontimeout = function(e) {
        console.log("timeout")
        reject({message: "I got timed out"});    
      };
    
      xhr.send(null);
    });
    pr.then(function(data) {
      console.log(data)
    }, function(err) {
      console.log(err)
    })

    Giving a higher timeout working code here

    If you use d3.v4 you can use timeout working code here