Reena Verma
Reena Verma

Reputation: 1685

onClick, wait for existing XMLhttprequest() to complete

I'm struggling a bit with this challenge...

I need to do three things:

The problem I'm having, is that when I click my button, the next page hasn't even had a chance to finish loading and my API check executes immediately.

I have looked at numerous solutions, async/wait, some suggested not to use setTimeout(). And I still can't seem to overcome the first hurdle, waiting for the page to finish loading and allowing the existing API call to finish.

How can I wait for an existing API call to finish running?

let button = document.getElementById("signin");
button.setAttribute("onClick", "fireTracking()");

function ajax(url) {
    return new Promise(function(resolve, reject) {
      var xhr = new XMLHttpRequest();
      xhr.onload = function() {
        resolve(this.responseText);
      };
      xhr.onerror = reject;
      xhr.open('GET', url);
      xhr.send();
    });
  }
  
function fireTracking() {
    ajax("www.myurl.com/getstatus")
    .then(function(result) {
    // Code depending on result
    console.log(result);
    console.log("fire event...")
  })
  .catch(function() {
    // An error occurred
  });
}

To confuse things, the URL of the page is the same. So essentially, I can't look out for a different URL.

I'm starting to think I might need to use a setTimeout()? IE, wait 1 second and then make a new API call?

Please note, this is code is running on top of an application. I'm using an AB Testing tool, so I'm essentially trying to get this to work, on top of already compiled code.

Upvotes: 0

Views: 1107

Answers (1)

Louys Patrice Bessette
Louys Patrice Bessette

Reputation: 33943

That button is submitting a form while triggering your fireTracking function.

So... That submit is refreshing your page and the result of the Ajax request is just lost.

You have to prevent the normal submit behavior.

So here is the "minimal change" to do from your code:

let button = document.getElementById("signin");
button.setAttribute("onClick", "fireTracking(event)");  // Add the event argument

function ajax(url) {
    return new Promise(function(resolve, reject) {
      var xhr = new XMLHttpRequest();
      xhr.onload = function() {
        resolve(this.responseText);
      };
      xhr.onerror = reject;
      xhr.open('GET', url);
      xhr.send();
    });
  }
  
function fireTracking(event) {  // Add the event argument
    event.preventDefault()  // Add this
    ajax("www.myurl.com/getstatus")
    .then(function(result) {
    // Code depending on result
    console.log(result);
    console.log("fire event...")
  })
  .catch(function() {
    // An error occurred
  });
}

But! a good practice would be to set an event handler for that button using .addEventListener(), like @epacarello mentionned.

Upvotes: 1

Related Questions