0

In this code , The main countries console.log( ) is always becoming null

but "countries in csv" console.log( ) is always turning out to be good. What is that I am missing here ? In the console , why am I am seeing that console.log("main countries:",cn) is being printed first rather than console.log("countries in csv")?

//in csv.js file : 
var rpc_csv = function()
{
    var countries = null;
    d3.csv("data/rpc_stas.csv", function(rpc_data)
    {
        //rpc_data is an array of json objects containing the data in from the csv
        //console.log("rpc_data:", rpc_data)
        countries = rpc_data.columns;
        console.log("countries in csv ", countries)
        return countries;
    });
    return countries;
}



// in script.js file : 
    
var cn = rpc_csv()
console.log("main contries:",cn);
<script src="https://d3js.org/d3.v4.min.js"></script>

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="js/d3.v4.js"></script>
    <script type="text/javascript" src="js/underscore-min.js"> </script>
    <script type="text/javascript" src="js/csv.js"></script>
  </head>
  <body>
    <div id="ratiopercountry"></div>
    <script src="js/script.js"></script>

  </body>
</html>
sus
  • 496
  • 1
  • 6
  • 14
  • define countries as a global variable – Harsh Patel Jan 17 '18 at 06:03
  • 4
    isn't `d3.csv` returning a promise, by any chance? In either case, it looks like the code is async and you need to wait for the return value before console logging – Adelin Jan 17 '18 at 06:06
  • Possible duplicate of [Javascript Promise return value](https://stackoverflow.com/questions/41177095/javascript-promise-return-value) – clemens Jan 17 '18 at 06:07

3 Answers3

1

This is because you function runs asynchronously and returns the null value before actually getting the countries data from the csv.

So you can use a callback to achieve what you need.

var rpc_csv = function(_callback)
{
    try{
        var countries = null;
        d3.csv("data/rpc_stas.csv", function(rpc_data)
        {
            //rpc_data is an array of json objects containing the data in from the csv
            //console.log("rpc_data:", rpc_data)
            countries = rpc_data.columns;
            console.log("countries in csv ", countries)
            return _callback(countries);
        });
        //return countries;
    }
    catch(ex){
    console.log(ex);
    return null;
    }



// in script.js file : 

var cn = null;
rpc_csv(function(countries){
    cn = countries;
    console.log("main contries:",cn);
})

Hope this helps!

sanatsathyan
  • 1,713
  • 12
  • 18
  • It doesn't return the `null` value. It actually leaves `countries` intact for a while (which was declared with a `null` value). If countries would've been declared as `1` at initialization, logging it with OPs code would've logged `1` instead of `null` – Adelin Jan 17 '18 at 06:12
0

d3.csv is an asynchronous function, meaning that the rpc_data will be returned at a different point of time to when the function rpc_csv returns.

So basically, you are going to always return null in the function, as it will run like the following.

//in csv.js file : 
var rpc_csv = function()
{
    var countries = null;
    // d3.csv is an asynchronous function. The callback supplied
    // will be executed once the csv file is read.
    return countries;
}

Ideally, you want to do the data processing inside of the callback supplied to the d3.csv function.

J. Lee
  • 513
  • 4
  • 15
0

Ok Let understand what is going on .

In your case the

console.log("main contries:",cn);
// execute before
console.log("countries in csv ", countries)

Explanation will explain how this happen .

First of d3.csv is I/O bound request when you call it . It execute asynchronously because it would be http ,file read , database all are executed in asynchronously .

Let take a example of your code . and change d3.csv( to settimeout .

Run this code will also work as your's because settimeout is i/o bound.

var rpc_csv = function()
{
    var countries = null;
      setTimeout(function(){  
          countries ="US";
console.log("countries in csv ", countries)
      }, 3000);

    return countries;
}



// in script.js file : 

var cn = rpc_csv()
console.log("main contries:",cn);

Hope this help you .

Himanshu sharma
  • 7,487
  • 4
  • 42
  • 75