Search code examples
javascriptxmlhttprequestjavascript-objects

Xhr: API Cryptocurrency price alert script returns wrong and duplicate values


This is a simple vanilla JS script that connects to the CoinMarketCap.com ticker API.

What it should do:

1) Retrieve coin data, store it in an object

2) Wait x amount of time (three minutes, in this case)

3) Repeat 1), to retrieve more recent data

4) Compare recent data and previous data

5) If a coin's value has gone up, console.log the alert

6) Repeat the process

What is does: The two objects (firstValue and secondValue) are duplicates. Also, when starting over (calling the main() function again), the content of these two objects fails to upate, and show the previous values.

// Variables

// Set first recorded value 
var firstValue;

// Set second value (most recent)
var secondValue;


// Get the obj from CoinMarketCap API
function getCoinValues() {
    var requestURL ="https://api.coinmarketcap.com/v1/ticker/?limit=10";
    var request = new XMLHttpRequest();
    request.open("GET", requestURL);
    request.send();

    // When loaded assign to obj variable and return it
    request.onload = function getUsdValues() {
        // Save data to the 'obj' object
        obj = JSON.parse(request.response);
        console.log("Retrieved coin data"); 
        };
    return obj;
}


// Wait 
function wait(ms){
    console.log("Waiting.")
    var start = new Date().getTime();
    var end = start;
    while(end < start + ms) {
    end = new Date().getTime();
     }          
}


// Compare two objects
function comparePrices (obj1, obj2) {
    // Take price from one array, compare to the other
    for (var i = 0; i < obj1.length; i++) {
            // console.log(JSON.stringify(obj2[i].id) + " OLD:" + obj1[i].price_usd + "NEW:" + obj2[i].price_usd)
            if (obj2[i].price_usd > obj1[i].price_usd) {
               console.log(JSON.stringify(obj2[i].id) + " has increased!");
               console.log("From $" + obj1[i].price_usd + " to $" + obj2[i].price_usd);

             }
        }

}


// Main function //

function main () {
    // Get 1st coin values
    console.log("Getting first values");
    firstValue = getCoinValues();

    // Wait
    console.log("Waiting")
    wait(30000);

    // Retrieve new values
    console.log("Getting second values")
    secondValue = getCoinValues();

    // Compare two sets of values
    console.log("About to compare prices")
    comparePrices(firstValue, secondValue);
    console.log("Prices compared")

    // Do it all again

    // "Emptying" the variables
    firstValue = null
    secondValue = null

    // Starting the main loop
    main();

}

main();

Why don't firstValue and secondValue display different results, even when prices have effectively varied in the ticker?

Please forgive any inappropriate use of the technical jargon as well as overall coding newbieness.


Solution

  • The OP code contains a number of technical and logical errors. Please see comments inside the fixed code.

    // Variables
    
    // Set first recorded value 
    //var firstValue; //no use
    
    // Set second value (most recent)
    //var secondValue; //no use
    
    //Save AJAX response here
    var currentValue = [];
    //define the const URL
    var requestURL = "https://api.coinmarketcap.com/v1/ticker/?limit=10";
    
    // Get the obj from CoinMarketCap API - wrong description
    //Process request to API
    function getCoinValues() {
        //var requestURL = "https://api.coinmarketcap.com/v1/ticker/?limit=10";
        var request = new XMLHttpRequest();
        request.open("GET", requestURL);
        //request.send();//dedine a handler first
        request.onreadystatechange = function () {
            if (this.readyState == 4 && this.status == 200) { //**this** is request
                var tmpObj = JSON.parse(this.responseText);
                if (currentValue && tmpObj) {//compare when both arrays exist
                    comparePrices(currentValue, tmpObj);
                }
                if (tmpObj) //response received and parsed
                    currentValue = tmpObj;
                //console.log(tmpObj);
            }
        }
        //now it is good time to send request
        request.send();
    
        // When loaded assign to obj variable and return it
        //request.onload = function getUsdValues() {
        //    // Save data to the 'obj' object
        //    obj = JSON.parse(request.response); //obj was never defined
        //    console.log("Retrieved coin data");
        //};
        //return obj; //never try to return anything from asynchronous function
    }
    
    
    // Wait 
    //Good to hang the system
    /*
    function wait(ms) {
        console.log("Waiting.")
        var start = new Date().getTime();
        var end = start;
        while (end < start + ms) {
            end = new Date().getTime();
        }
    }
    */
    
    // Compare two objects (arrays in fact)
    function comparePrices(obj1, obj2) { //usage: comparePrices(current,new)
        console.log(new Date().toLocaleTimeString());
        // Take price from one array, compare to the other
        for (var i = 0; i < obj1.length; i++) {
            // console.log(JSON.stringify(obj2[i].id) + " OLD:" + obj1[i].price_usd + "NEW:" + obj2[i].price_usd)
            if (obj2[i].price_usd > obj1[i].price_usd) {
                //console.log(JSON.stringify(obj2[i].id) + " has increased!"); //no need to stringify.
                console.log(obj2[i].id + " has increased! From $" + obj1[i].price_usd + " to $" + obj2[i].price_usd);
            } else if (obj2[i].price_usd < obj1[i].price_usd) {
                console.log(obj2[i].id + " has decreased! From $" + obj1[i].price_usd + " to $" + obj2[i].price_usd);
            } else {
                console.log(obj2[i].id + " No change $" + obj2[i].price_usd);
           }
        }
    }
    
    // Main function //
    
    function main() {
        getCoinValues();
        setTimeout(main, 30000);//run again in 30 sec
        return;
        //All remaining code is wrong
    
        //// Get 1st coin values
        //console.log("Getting first values");
        //firstValue = getCoinValues();
    
        //// Wait
        //console.log("Waiting")
        //wait(30000);
    
        //// Retrieve new values
        //console.log("Getting second values")
        //secondValue = getCoinValues();
    
        //// Compare two sets of values
        //console.log("About to compare prices")
        //comparePrices(firstValue, secondValue);
        //console.log("Prices compared")
    
        //// Do it all again
    
        //// "Emptying" the variables
        //firstValue = null
        //secondValue = null
    
        //// Starting the main loop
        //main();
    
    }
    
    main();
    

    I was thinking to create a code snippet but decided not to do it.