Search code examples
javascriptapixmlhttprequest

Can not make XMLHttpRequest to 3 separate API urls


Before I start, here is the API. Super simple: https://www.cryptonator.com/api

To note, I have worked with api before, but i used a await async function, but for some reason I couldn't get that to work....but I found a tutorial for doing this with XML http request, so I decided to just move forwards doing it in XML because I was able to make a simple Bitcoin ticker.

I am building a simple widget to display the prices of Bitcoin, Litecoin, and Ethereum using the cryptonator API. Like I said above, I made a bitcoin ticker with the first function ( see code below ), and it works great. However, I am having issues trying to get 3 different currencies.

Here is what I am trying to do.

var url = "https://api.cryptonator.com/api/ticker/btc-usd";

xmlhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
    var json = JSON.parse(this.responseText);
    parseJson(json);
  }
};

xmlhttp.open("GET", url, true);
xmlhttp.send();

function parseJson(json) {

  var usdValue = json["ticker"]["price"];
  document.getElementById("data").innerHTML = usdValue;

  var usdValue = usdValue.replace(/[^\d.\-]/g, "");
  var usd = parseFloat(usdValue);
  document.getElementById("data").innerHTML = "$ " + usd.toFixed(2);
}



// 
// 

var xmlhttp2 = new XMLHttpRequest();
var url2 = "https://api.cryptonator.com/api/ticker/ltc-usd";

xmlhttp2.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var json = JSON.parse(this.responseText);
      parseJson(json);
    }
  };

  xmlhttp2.open("GET", url2, true);
  xmlhttp2.send();

  function parseJson(json) {

    var LTCusdValue = json["ticker"]["price"];
    // document.getElementById("data2").innerHTML = LTCusdValue;

    var LTCusdValue = LTCusdValue.replace(/[^\d.\-]/g, "");
    var LTCusd = parseFloat(LTCusdValue);
    document.getElementById("data2").innerHTML = "$ " + LTCusd.toFixed(2);
  }


//   
// 
// 

var xmlhttp3 = new XMLHttpRequest();
var url3 = "https://api.cryptonator.com/api/ticker/eth-usd";

xmlhttp3.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      var json = JSON.parse(this.responseText);
      parseJson(json);
    }
  };

  xmlhttp3.open("GET", url3, true);
  xmlhttp3.send();

  function parseJson(json) {

    var ETHusdValue = json["ticker"]["price"];
    // document.getElementById("data3").innerHTML = ETHusdValue;

    var ETHusdValue = ETHusdValue.replace(/[^\d.\-]/g, "");
    var ETHusd = parseFloat(ETHusdValue);
    document.getElementById("data3").innerHTML = "$ " + ETHusd.toFixed(2);
  }

As you can see, I am trying to make 3 request to 3 different APis, but it isn't working. If I comment out all but one of these functions, it works fine. My issues comes when i try to use all 3 at once. If i use Bitcoin and Litecoin only, it will actually work, but will just break again once I try to use the 3rd function ( to get ethereum price ).


Solution

  • The parseJson function is defined three times. This means that every time you write the function it will overwrite the previous definition. So in your case only the last parseJson function will be used for all three requests. You could do a couple of things.

    Write three different variations. (Bad practice)

    Though this would be the less favorable of the options. It will require you to have repeated code copied multiple times. This can be done more efficiently.

    function parseJson1(json) {
      ...
    }
    
    function parseJson2(json) {
      ...
    }
    
    function parseJson3(json) {
      ...
    }
    

    Add an argument to the function. (Good practice)

    Give the parseJson function a second argument that selects the element to output the value. This should be the id of the element you'll want to select.
    This is the better solution because it only requires you to write a function once and call it multiple times accounting for the variations.

    function parseJson(json, id) {
      var output = document.getElementById(id); // Select the element based on the id.
      if (output === null) { // If element is not found, stop the function.
        return;
      }
      var price = json["ticker"]["price"];
      var usdValue = price.replace(/[^\d.\-]/g, "");
      var usd = parseFloat(usdValue);
      output.innerHTML = "$ " + usd.toFixed(2);
    }
    

    The last technique is applicable to the rest of your code. Be aware of repeating yourself. You'll write much cleaner and better code when you only have to write something once.