1

I believe this may be an issue with async or promises, however, this concept has been a struggle for me to grasp. I have spent much time researching questions relating to papaparse and promises, but believe I am still not grasping some simple concept.

Overview

In the below code, a .csv file is gathered from the user, converted into an Object using PapaParse, then distance/duration values are added to the data from GoogleMaps Distance Matrix and finally, the intent is to return this data back to the user as a .csv containing this combined information.

In downloadCSV(), I am able to log the Object which results from getDistTime. However, I am unable to iterate over this object or send it to papa.unparse to convert to a .csv. Below the code, I have attached an image of the structure of arr within downloadCSV().

I have spent much time researching questions here, and on the papaparse repo. I would appreciate any help on how to best proceed.

Contents of arr: I'm good

Code


    $("#submit").click(function(){
        //REMOVE THIS LINE BEFORE LIVE OR VALIDATION WILL BE DUN GOOFED
        event.preventDefault();
        getData();
    });


    function getData(){
        var csv = document.getElementById('exampleFormControlFile1').files[0];
        // Parse CSV string
        Papa.parse(csv, {
            header: true,
            complete: function(results) {
                var final_rows = getDistTime(results)
                downloadCSV(final_rows) 
            }
        });
    } // end getData


    function downloadCSV(arr){
        //console.log(arr) shows the results
        // but trying to iterate over arr or unparsing shows undefined
        console.log(arr)
        csv = Papa.unparse(arr)

       ...more csv export code
    }


    function getDistTime(resources){
        var rows = []
        const promiseArr = [];
        for (var i = 0; i < resources.data.length; i++) {
            var origin1 = $("#citystate").val();;
            var destinationA = resources.data[i]['DEMOBILIZATION CITY'] + ',' + resources.data[i]['DEMOBILIZATION STATE'];
            promiseArr.push(googleRequest(origin1, destinationA));
        }

        Promise.all(promiseArr)
        .then((resultsArr) => {
            resultsArr.forEach((result, i) => 
            pushToRows(resources.data[i], result, rows));
        
        })
        return rows
    } // end getDistTime


    function pushToRows(resources, dist_dur, rows){
        resources["DISTANCE_MI"] = dist_dur[0];
        resources["ACTUAL_DUR_HR"] = dist_dur[1];
        resources["FINANCE_DUR_HR"] = (dist_dur[0] / 45.0).toFixed(2)
        rows.push(resources)   
    } // end pushToRows

jclark754
  • 914
  • 2
  • 12
  • 30

1 Answers1

1

getDistTime is performing an async action and therefore rows is returning empty before the Promise.all has resolved as you wont have pushed any data to it until that promise resolves.

Looks like you'll need to await the result of getDistTime or change how get data works, not sure you're using async await so simplest way is to just return that Promise.all and then only download the csv once its returned and resolved in your complete callback.

for example you could do

function getData(){
    var csv = document.getElementById('exampleFormControlFile1').files[0];
    // Parse CSV string
    Papa.parse(csv, {
        header: true,
        complete: function(results) {
            getDistTime(results).then(finalRows => downloadCSV(finalRows));
            
        }
    });
} // end getData

function getDistTime(resources){
    var rows = []
    const promiseArr = [];
    for (var i = 0; i < resources.data.length; i++) {
        var origin1 = $("#citystate").val();;
        var destinationA = resources.data[i]['DEMOBILIZATION CITY'] + ',' + resources.data[i]['DEMOBILIZATION STATE'];
        promiseArr.push(googleRequest(origin1, destinationA));
    }

    return Promise.all(promiseArr)
    .then((resultsArr) => {
        resultsArr.forEach((result, i) => 
            pushToRows(resources.data[i], result, rows)
        );
    
        return rows
    })
} // end getDistTime
Dan Purdy
  • 371
  • 2
  • 6
  • thank you so much for your help, this worked great. I awarded you all of the things! – jclark754 Jul 15 '20 at 01:12
  • 1
    Glad i could help. It's worth noting that console.log is notorious for evaluating in a lazy way so you cannot always guarantee that what it logs is what was actually there at the time of invocation probably why you were logging values but not actually passing anything to the download function - https://stackoverflow.com/questions/4057440/is-chromes-javascript-console-lazy-about-evaluating-arrays – Dan Purdy Jul 15 '20 at 01:13