0

Reading a CSV file, I can't return the data read. console.log(data) contains what I need, but it's not returning data (e.g. when calling the readCSV function):

export default function readCSV(filename) {
   let parser = parse({columns: true, trim: true, skip_empty_lines: true}, function(err, data){
       console.log(data);
       return data;
    });

    fs.createReadStream(__dirname + '/' + filename).pipe(parser);
    return parser;
}

This gives me the parser instance and not the data - tried many variations of it. How do I return data? What am I missing as a concept in JS? I'm using the node-csv-parse lib.

dh762
  • 2,259
  • 4
  • 25
  • 44
  • Since `parse()` behaves asynchronously, you won't be able to just `return` its result. The actual order of execution doesn't permit it. There are a handful of alternate options, each discussed in detail in "[How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call)" – Jonathan Lonowski Mar 17 '18 at 17:02

1 Answers1

2

I'm guessing it's because parse() is an async function. You would either want another callback to retrieve the value, or use the new trendy approach of using promises:

export default function readCSV(filename) {
   return new Promise((resolve, reject) => {
       let parser = parse({columns: true, trim: true, skip_empty_lines: true}, function(err, data){
       if (err)
           reject();
       else
           resolve(data);
    });
     fs.createReadStream(__dirname + '/' + filename).pipe(parser);
   })
}

which you would then use a such:

readCSV("somefile").then((data) => {
   console.log(data)
})
.catch(()=>{
   console.log("Something went wrong")
})

Or use an async function:

async function doThing() {
   let data = await readCSV("somefile");
   console.log(data)
}
Slava Knyazev
  • 5,377
  • 1
  • 22
  • 43
  • Good suggestion. Though, probably shouldn't swallow the error: `reject(err);`. Also, [`util.promisify()`](https://nodejs.org/dist/latest-v9.x/docs/api/util.html#util_util_promisify_original) could be useful here. – Jonathan Lonowski Mar 17 '18 at 17:15
  • alright, this is under the assumption that the file is already loaded. Your example does not care for `createReadStream` (see [**here**](https://github.com/adaltas/node-csv-parse/blob/master/samples/fs_read.js#L9)). I fail to make it work with that, how do I build it in so that it reads from disk? – dh762 Mar 17 '18 at 18:17
  • also, not sure if `parse` is actually async: https://github.com/adaltas/node-csv-parse/blob/master/lib/index.js#L26 – dh762 Mar 17 '18 at 18:20
  • 1
    I just forgot to add that line back in – Slava Knyazev Mar 17 '18 at 18:23