-1

I am trying to build a simple web app that pulls API data on the price of Bitcoin. I am able to parse the data and extract the price. However, given the asynchronous nature of Node.js, when I try to return the data it returns before the http request is complete.

This is why I inserted the callback function. However, when it returns the price it is still undefined. Hence, I assume that the request is not complete when the return is sent even with the callback?

I have also heard of other solutions such as promises and async yet I cannot find a way to return the price variable from the function. I need to be able to do this so that I can do separate calculations on the returned variable.

Disclaimer: I am a node newbie so any help would be appreciated

var https = require('https');

function myCallback(result) {
 return result;
}

var price = 0;
function getData(callback) {
 var url = "https://api.coinbase.com/v2/prices/spot?currency=USD";
 https.get(url, function(res){
 var body = '';

 res.on('data', function(chunk){
  body += chunk;
 });

 res.on('end', function(){
  var exData = JSON.parse(body);
  price = Number((exData.data.amount))*14.5;
  callback(price);
 });
}).on('error', function(e){
 console.log("Got an Error: ", e);
});
};

var y = getData(myCallback);
console.log(y);
  • You're assigning `y` to the return value of the `getData` function not to the return value of `myCallback`. You can find [HERE](https://stackoverflow.com/a/14220323/1552587) a very detailed explanation on how you could do this. – Titus Nov 12 '17 at 12:48
  • @Titus, thanks for that. I see what you mean. Let me see what I can do. – Janet Preston Nov 12 '17 at 13:03

1 Answers1

0

The hard thing when you start in javascript is start thinking in asynchronous operations. When console.log(y) is executed the HTTPS call isn't completed yet so it can't be called that way once majorly IO functions in node are non-blocking. What you need to do is to call console.log inside the myCallback function.

var https = require('https');

function myCallback(result) {
    console.log(result);
}

var price = 0;
function getData(callback) {
    var url = "https://api.coinbase.com/v2/prices/spot?currency=USD";
    https.get(url, function(res){
        var body = '';

        res.on('data', function(chunk){
            body += chunk;
        });

        res.on('end', function(){
            var exData = JSON.parse(body);
            price = Number((exData.data.amount))*14.5;
            callback(price);
        });
    }).on('error', function(e){
        console.log("Got an Error: ", e);
    });
}

getData(myCallback);

EDIT: The thing is, you can set the value of a variable outside the callback by you still have to ensure that you'll be using this variable only after the attribution. You still have to use callbacks one way or another.

There's another way of pass callbacks around and it has a nicer way for doing that, promises. I believe that is what you're looking for.

var https = require('https');

var price = 0;
function getData() {
    var promise = new Promise(function(resolve, reject) {
        var url = "https://api.coinbase.com/v2/prices/spot?currency=USD";
        https.get(url, function(res){
            var body = '';

            res.on('data', function(chunk){
                body += chunk;
            });

            res.on('end', function(){
                var exData = JSON.parse(body);
                price = Number((exData.data.amount))*14.5;
                resolve(price);
            });
        }).on('error', function(e){
            console.log("Got an Error: ", e);
            reject(e);
        });
    })
    return promise;
}

var y = getData()
y.then(function (result) {
    console.log('price: ' + result);
});
  • thanks for your response. That is indeed what I should do if I wanted to log the data. The reason I saved it as a "y" variable was to see whether the return variable could be saved as data outside of the functions for later use. I want to be able to use the price in other calculations outside of the function, hence the need to return it as a number. I know that as it stands my code has a problem in that I am setting my "y" variable to getData instead of the callback. Moreover, when calling the global "price" variable outside of the function it still is undefined. Stuck on this.. – Janet Preston Nov 12 '17 at 14:27
  • I updated the answer. Please take a look. – Rafael P. Miranda Nov 12 '17 at 16:51