Search code examples
javascriptjsoncsvparsingpapaparse

Array index returns undefined after push - Papa Parse


I used Papa Parse to parse a .csv file, and pushed the result to an empty array called parsed_data. I am able to use console.log(parsed_data), and view the arrays produced. However, when I try to index the data, for example, console.log(parsed_data[0]), the result is undefined. Not sure what's going wrong here.

Example code:

    let parsed_data = [];
    const data_url = "acdata.csv";
    async function getData() {
        const response = await fetch(data_url);
        const blob = await response.blob();
        const data = Papa.parse(blob, {
            complete: function(results) {
                //console.log("Finished:", results.data);   
                parsed_data.push(results.data); 
            }
        });

    };
    console.log(parsed_data);
    getData();


Solution

  • Since Papa parse complete callback is called asynchronously, you'll need to wait for that to complete - however, papa parse doesn't seem to use Promises, so, you can "promisify" the parse function like so

    const papaParsePromise = blob => new Promise(resolve => Papa.parse(blob, { complete: resolve }));
    

    Another way of looking at that function, if you don't understand the => notation, is

    function papaParsePromise(blob) {
        return new Promise(function(resolve) {
            Papa.parse(blob, { 
                complete: function(data) {
                    resolve(data);
                }
            );
        });
    }
    

    that returns a promise that resolves to the data that is passed to the complete callback

    Your code would also need to wait for the promise returned by getData before it can use anything in that data. Unless your code is inside another async function, you'll need to use promise .then method, as below

    const data_url = "acdata.csv";
    async function getData() {
        // create a function that returns a Promise that resolves when papa parse complete is called
        const papaParsePromise = blob => new Promise(resolve => Papa.parse(blob, { complete: resolve }));
        const response = await fetch(data_url);
        const blob = await response.blob();
        const data = await papaParsePromise(blob);
        return data;
    };
    getData()
    .then(parse_data => {
        console.log(parsed_data);
        console.log(parsed_data[0]);
        // i.e. do what you need with parsed_data here
    });
    

    if, however, you are calling getData inside an async function - along with the changes to getData above, you can simply use await getData() to wait for the value - i.e.

    async function someFunction() {
        const parsed_data = await getData();
        // do what you need with parsed_data here
    }