0

I'm trying to parse a json retrieved from the web (https://api.coinmarketcap.com/v1/ticker/?limit=3) and be able to select the name and price_usd. For reference:

[
{
    "id": "bitcoin", 
    "name": "Bitcoin", 
    "symbol": "BTC", 
    "rank": "1", 
    "price_usd": "16148.3", 
    "price_btc": "1.0", 
    "24h_volume_usd": "18799600000.0", 
    "market_cap_usd": "270147332945", 
    "available_supply": "16729150.0", 
    "total_supply": "16729150.0", 
    "max_supply": "21000000.0", 
    "percent_change_1h": "-0.28", 
    "percent_change_24h": "-4.64", 
    "percent_change_7d": "45.79", 
    "last_updated": "1512792553"
}, 
{
    "id": "ethereum", 
    "name": "Ethereum", 
    "symbol": "ETH", 
    "rank": "2", 
    "price_usd": "471.833", 
    "price_btc": "0.0296001", 
    "24h_volume_usd": "2170950000.0", 
    "market_cap_usd": "45401368016.0", 
    "available_supply": "96223384.0", 
    "total_supply": "96223384.0", 
    "max_supply": null, 
    "percent_change_1h": "0.01", 
    "percent_change_24h": "9.29", 
    "percent_change_7d": "0.65", 
    "last_updated": "1512792556"
}, 
{
    "id": "bitcoin-cash", 
    "name": "Bitcoin Cash", 
    "symbol": "BCH", 
    "rank": "3", 
    "price_usd": "1510.48", 
    "price_btc": "0.094759", 
    "24h_volume_usd": "2229320000.0", 
    "market_cap_usd": "25444318815.0", 
    "available_supply": "16845188.0", 
    "total_supply": "16845188.0", 
    "max_supply": "21000000.0", 
    "percent_change_1h": "0.6", 
    "percent_change_24h": "1.29", 
    "percent_change_7d": "2.64", 
    "last_updated": "1512792581"
    }
]

Here's the code I currently have:

var url = 'https://api.coinmarketcap.com/v1/ticker/?limit=3';
var dataResponse = '';
var body = '';

function retrieveData() {
    https.get(url, function(res){
        body = '';

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

        res.on('end', function() { 
            dataResponse = JSON.parse(body);
        });


    }).on('error', function(e) {
          console.log("Error: ", e);
    });

} 

retrieveData();

var temp = (dataResponse[0]);

console.log(temp);

I want to be able to get something like and be able to select the name and price:

        "id": "bitcoin", 
        "name": "Bitcoin", 
        "symbol": "BTC", 
        "rank": "1", 
        "price_usd": "16148.3", 
        "price_btc": "1.0", 
        "24h_volume_usd": "18799600000.0", 
        "market_cap_usd": "270147332945", 
        "available_supply": "16729150.0", 
        "total_supply": "16729150.0", 
        "max_supply": "21000000.0", 
        "percent_change_1h": "-0.28", 
        "percent_change_24h": "-4.64", 
        "percent_change_7d": "45.79", 
        "last_updated": "1512792553"

The error I get is that it logs an undefined. I'm not sure what I'm doing wrong. How would I go selecting the name also? Would I split each block into an array and select them by indexing?

newang
  • 179
  • 2
  • 2
  • 7
  • 2
    `retrieveData` is async, `console.log` executes before `retrieveData` finishes – kkkkkkk Dec 09 '17 at 04:25
  • I would recommend you to read promise and async/await for coding in node.js . This usually happens when we are beginners . below answer will work for you . – Himanshu sharma Dec 09 '17 at 04:59

4 Answers4

1

Make your function accept a callback Like this

function retrieveData(callback) {
    https.get(url, function(res){
        body = '';
        res.on('data', function(chunk) {
            body += chunk;
        });

        res.on('end', function() { 
            var dataResponse = JSON.parse(body);
            callback(dataResponse,null);
        });
    }).on('error', function(e) {
          console.log("Error: ", e);
            callback(null,e)
        });
} 

Then call it like this,

retrieveData(function (dataResponse, err) {
 if (err) console.log(err);
 else {
   var temp = (dataResponse[0]);
   console.log(temp);
 }
});
vibhor1997a
  • 2,336
  • 2
  • 17
  • 37
0

Your issue is that the function receiveData is asynchronous and the console.log is actually ran before the dataResponse array is set. There is a good write up about asynchronous code and how to handle it here: How do I return the response from an asynchronous call?

Peter Grainger
  • 4,539
  • 1
  • 18
  • 22
0

You need to remember that the callbacks for .on and .end will get executed after the request to the url is fulfilled.

To access that after you can wrap your function in a promise and use .then like below.

PROMISES Check out this link for a better understanding of asynchronous processing.

function retrieveData() {
  return new Promise((resolve, reject) => {
    https.get(url, function(res){
        body = '';

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

        res.on('end', function() {
          resolve(JSON.parse(body));
        });


    }).on('error', function(e) {
        reject(e);
    });
  })  
}

retrieveData().then(response => {
  console.log(response[0]);
}).catch(error => {
  console.log(error)
})
Nandu Kalidindi
  • 6,075
  • 1
  • 23
  • 36
0

So I think you're already there, all ya need to do is log the "dataResponse" to console. Since "dataResponse" is an array of objects, you can simply output the objects to the console with simple javascript. This is how it'd look like:

```

var https = require ("https")

var url = 'https://api.coinmarketcap.com/v1/ticker/?limit=3';

function retrieveData () {
    https.get (url, function (res){
        body = '';

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

        res.on('end', function () { 
            dataResponse = JSON.parse (body);
            console.log (dataResponse[0])
        });


    }).on ('error', function (e) {
          console.log ("Error: ", e);
    });

} 

retrieveData ()

```

Ari
  • 1
  • 2