'How does d3.csv() work without non-arrow functions?

I am trying to understand the interchangeability of arrow functions vs ordinary functions for d3.csv() calls and promises.

  1. Using d3.csv(), I can successfully return and load a CSV file with arrow function syntax, which returns arrays:

    let fp = "data_file.csv"
    let data = d3.csv(fp).then( res => data = res)
    
    > Array(30)
    
  2. However, I am not able to load the same using ordinary function syntax - this actually returns a Promise object. I do not know how to extract the results from the object, but the PromiseResult seems to contain the array as above:

    let fp = "data_file.csv"
    let data = d3.csv(fp).then( function(res) {
        return res
    })
    
    > Promise
    
  3. But if I declare 'data' first, and execute a d3.csv call and bind data within it, I successfully get the array data directly from d3.csv(), as in (1) above:

    let data;
    d3.csv(fp).then( function(res) {
        data = res
    })
    
    > Array(30)
    
  4. Yet if I declare/define data within d3.csv(), the code entirely fails:

    d3.csv(fp).then( function(res) {
        let data = res
    })
    
    > ReferenceError: data is not defined at <anonymous>:1:1
    

Questions:

  1. Why does example (2) fail, and not retrieve the Array directly?

  2. If example (2) does not work, how does example (3) succeed?

  3. Why does example (4) fail entirely?

  4. How do I extract the array contained in a PromiseResult/Promise object returned by d3.csv()?

  5. How do I make d3.csv() interchangeable between arrow functions and ordinary functions syntax?

I've looked at various d3.csv()-related questions and promise-related questions, but none seem to address this issue specifically. In particular, these two questions don't answer what I've posed.



Solution 1:[1]

  1. Why does example (2) fail, and not retrieve the Array directly?

Because you made two changes, not just one, between your arrow and traditional function approaches.

  • You changed from arrow function syntax to traditional function syntax, and

  • You moved the assignment of data outside the function, assigning it the return value of then instead of assigning it res

The difference in results was because of the second change, not the first.

  1. If example (2) does not work, how does example (3) succeed?

Because you undid the change that made it fail, which had nothing to do with function syntax.

  1. Why does example (4) fail entirely?

It doesn't, but data is declared within the fulfillment callback, so you can only use it within the fulfillment callback.

  1. How do I extract the array contained in a PromiseResult/Promise object returned by d3.csv()?

Using either your example (1) or your example (3) (or await within an async function or at the top level of a module in environments supporting top-level await). The result is only available when the promise is fulfilled, not before. You can't get data as a return value from then. More:

  1. How do I make d3.csv() interchangeable between arrow functions and ordinary functions syntax?

See above, it has nothing to do with function syntax.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1