Ben Lindsay
Ben Lindsay

Reputation: 1796

javascript store set variable from within function

I have a file data.json with the contents: {"id": "foo", "value": "bar"}. I have another file index.html in the same directory with the following contents:

<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
  var datavar;
  d3.json("data.json", function(d) { datavar = d; console.log(datavar); });
  console.log(datavar);
</script>

When I open index.html in a web browser, the first console.log(datavar) call outputs {id: "foo", value: "bar"}. The second one outputs undefined. I was under the impression that since I initialized datavar outside of the function, changes I make to it would last once we're back out of the function. How can I store data from within the function that lasts outside the function?

Upvotes: 0

Views: 161

Answers (2)

Alex Taker
Alex Taker

Reputation: 203

Your assumption that because the variable is initialized outside of the function it will be stored longer than the function is correct. What is incorrect is the order in which they get hit. d3.json calls an asynchronous function, which lets the rest of the application keep running while loading. So the console.log after the d3.json call happens (undefined), and then at some later time the data.json is loaded and the correct info is logged.

If you want to use this data you need to wait for it to return and only use it in a callback function. The way you are currently setting the variable will work, but you'd have to tell any code using it to re-run so it runs after the data from the file is loaded.

Upvotes: 1

ginman
ginman

Reputation: 1315

You are correct in your assumption that a variable defined at the global level, and then changed within a function will persist the change outside of said function.

However, this is outputting 'undefined' because it is an asynchronous operation. This means that the code changing 'datavar' may not have executed before you log it. If you add a note to your console logs, i.e. console.log('inside d3', datavar) and console.log('outside d3', datavar) you may be surprised to see the 'outside d3' execute first.

Async loading is most definitely what you want - so you should tailor your actual code accordingly. Please feel free to provide more details if you run into issues.

If you absolutely need to load the data synchronously, see this SO answer: How do I load JSON data synchronously with d3.js?

Upvotes: 3

Related Questions