Reputation: 516
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>
Upvotes: 0
Views: 432
Reputation: 7891
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 .
Upvotes: 0
Reputation: 1763
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!
Upvotes: 1
Reputation: 533
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.
Upvotes: 0