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"]
1

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

5 Comments

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?
Yes, it's asynchronous, but that doesn't change how the browser deals with await.
Can you please also help me with the 2nd questions: why await works in google chrome console, but not in the javascript?
@Frank It's not just Chrome, it works in most browsers' dev tools. This is probably a good read: developers.google.com/web/updates/2017/05/…
@Frank This link is even better, it explains nicely why you don't need the async in the console: medium.com/@tomsu/…. I added this to the answer.
0

Please use

<script type="text/javascript">

Instead of

<script>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.