3

I am trying to reproduce the grouped bar chart using D3 from Observable. I am running the script on Chrome, with D3.v5.

In the script I have:

var data = Object.assign(await d3.csv("https://gist.githubusercontent.com/mbostock/3887051/raw/805adad40306cedf1a513c252ddd95e7c981885a/data.csv",
    d3.autoType), {
    y: "Population"
});

When I ran it in the HTML, it shows the following error:

Uncaught SyntaxError: missing ) after argument list

I tried it on the Chrome console, it works fine.

HTML file content:

<!DOCTYPE html>
<meta charset="utf-8">

<body>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>


var margin = {top: 10, right: 10, bottom: 20, left: 40},
    width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;
 

var data = Object.assign(await d3.csv("https://gist.githubusercontent.com/mbostock/3887051/raw/805adad40306cedf1a513c252ddd95e7c981885a/data.csv", d3.autoType), {y: "Population"});
 

</script>

When successful, data should be a object as the following:

[{…}, {…}, {…}, {…}, {…}, {…}, columns: Array(8), y: "Population"]
Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
Frank
  • 152
  • 2
  • 11
  • I also found this link helpful for me to understand how to do something with data after the async d3.csv (or d3.json) call. https://stackoverflow.com/questions/9491885/csv-to-array-in-d3-js/9492055 – Frank Jul 05 '19 at 15:19

2 Answers2

4

What you want is to move the code from the Observable notebook to a common JavaScript script. In that case, you cannot use await like you did.

If you have a look at the MDN page, you'll see very clearly that:

The await operator is used to wait for a Promise. It can only be used inside an async function. (emphasis mine)

That being said, this async function with your code inside it will work:

(async function foo() {
  const data = Object.assign(await d3.csv("https://gist.githubusercontent.com/mbostock/3887051/raw/805adad40306cedf1a513c252ddd95e7c981885a/data.csv", d3.autoType), {
    y: "Population"
  });
  console.log(data)
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

That code worked inside an Observable notebook because of the way notebooks work:

Observable already supported async generators in a sense: you can also define a (synchronous) generator cell that yields promises. Observable waits until the previous promise resolves before pulling the next one from the generator. (source)

Finally, regarding your observation that the code worked on Chrome's console: It's not just Chrome, that code will work without the async in most modern browsers' console. The explanation is that the code in the console is wrapped in async by default. Here is a good reading: https://medium.com/@tomsu/devtools-tips-day-7-the-simple-joys-of-async-console-578f4ce67df4

Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
  • Thank you very much for your answer. Just to clarify, isn't d3.csv an async function? I googled it and found it seems to be asynchronous. Second questions, I don't understand why it works in the google chrome console, but not the pure javascript. Can you please shed light on it? – Frank Jul 03 '19 at 18:32
  • 1
    Yes, it's asynchronous, but that doesn't change how the browser deals with `await`. – Gerardo Furtado Jul 04 '19 at 01:33
  • Can you please also help me with the 2nd questions: why await works in google chrome console, but not in the javascript? – Frank Jul 05 '19 at 12:54
  • 1
    @Frank It's not just Chrome, it works in most browsers' dev tools. This is probably a good read: https://developers.google.com/web/updates/2017/05/devtools-release-notes – Gerardo Furtado Jul 05 '19 at 13:11
  • 1
    @Frank This link is even better, it explains nicely why you don't need the `async` in the console: https://medium.com/@tomsu/devtools-tips-day-7-the-simple-joys-of-async-console-578f4ce67df4. I added this to the answer. – Gerardo Furtado Jul 05 '19 at 13:21
0

Please use

<script type="text/javascript">

Instead of

<script>
Atif Tariq
  • 2,650
  • 27
  • 34