JavaScript code causing API response to output twice

Viewed 317

My JavaScript code below appears to be working but it is just that the returned API response output is appearing twice. I'd like it to appear only one time.

My guess is that perhaps it is my incorrect use of the success_callback, but I'm not sure how to modify that to get it to work properly. I'm also not sure if I'm making two requests to the API or if it's just a case where the returned response is getting output twice.

Here's my code. What's causing this and how do I correct it?

var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
const Locations = require("./locations.js");

// Init API connector
var r = new API_Connector();

// Get the tour
r.tour(Locations.LOCATIONS, function(result) {

  // Success - Parse the data
  const parsedData = JSON.parse(result);

  // This loop steps through the JSON response and outputs the data           
  for (i = 0; i < parsedData.count; i++) {
    console.log(parsedData.route[i]);
  }

}, function(error) {
  // Error
  console.log(error);
});

function API_Connector() {
  this.tour = (_LOCATIONS, success_callback, error_callback) => {

    // Init the request object
    var httpRequest = new XMLHttpRequest();
    if (!httpRequest) {
      alert('Cannot create an XMLHttpRequest instance');
      return false;
    }

    var ulog = Buffer.from('username:password').toString('base64');

    // Set up the request and send it
    httpRequest.open('POST', "https://myapi.test.com/tour");
    httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    httpRequest.setRequestHeader("Authorization", "Basic " + ulog);

    var params = "locations=" + JSON.stringify(Locations.LOCATIONS);
    httpRequest.send(params);

    // Receive the response
    httpRequest.onreadystatechange = function() {

      if (httpRequest.status === 200) {
        success_callback(httpRequest.responseText);
        console.log('Success');
      } else {
        error_callback(httpRequest.responseText);
        console.log('No success');
      }
    };
  };
}

Here's the output:

{ name: '40844, Home', arrival: 0, distance: 0 }
{ name: '40758, Purge', arrival: 44, distance: 55.3 }
{ name: '40810, Purge', arrival: 97, distance: 132.6 }
{ name: '40806, Purge', arrival: 180, distance: 253.6 }
{ name: '40804, Purge', arrival: 195, distance: 268.3 }
{ name: '40805, Purge', arrival: 232, distance: 317.6 }
{ name: '40861, Recycle', arrival: 290, distance: 400.5 }
Success
{ name: '40844, Home', arrival: 0, distance: 0 }
{ name: '40758, Purge', arrival: 44, distance: 55.3 }
{ name: '40810, Purge', arrival: 97, distance: 132.6 }
{ name: '40806, Purge', arrival: 180, distance: 253.6 }
{ name: '40804, Purge', arrival: 195, distance: 268.3 }
{ name: '40805, Purge', arrival: 232, distance: 317.6 }
{ name: '40861, Recycle', arrival: 290, distance: 400.5 }
Success
1 Answers

The readystatechange event occurs multiple times during the lifetime of an AJAX request. You need to check httpRequest.readyState to tell if you're at the final response stage. Otherwise you'll call success_callback() multiple times.

httpRequest.onreadystatechange = function() {
  if (httpRequest.readyState == 4) {
    if (httpRequest.status === 200) {
      success_callback(httpRequest.responseText);
      console.log('Success');
    } else {
      error_callback(httpRequest.responseText);
      console.log('No success');
    }
  }
};

See XMLHttpRequest.readyState documentation for the different state values.

Related