Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reading a csv file async - NodeJS

I am trying to create a function where I can pass file path and the read the file in async way. What I found out was that it supports streams()

const fs = require('fs');
var parse = require('csv-parse');
var async = require('async');

readCSVData = async (filePath): Promise<any> => {
    let csvString = '';
    var parser = parse({delimiter: ','}, function (err, data) {
        async.eachSeries(data, function (line, callback) {
            csvString = csvString + line.join(',')+'\n';
            console.log(csvString) // I can see this value getting populated
        })
      });
      fs.createReadStream(filePath).pipe(parser);
}

I got this code from here. but I am new to node js so I am not getting how to use await to get the data once all lines are parsed.

const csvData = await this.util.readCSVData(path)
like image 742
Samuel Avatar asked Aug 06 '18 14:08

Samuel


People also ask

How do I read a csv file in node JS?

You will use the fs module's createReadStream() method to read the data from the CSV file and create a readable stream. You will then pipe the stream to another stream initialized with the csv-parse module to parse the chunks of data. Once the chunks of data have been parsed, you can log them in the console.

How do I read async in node JS?

readFileSync() method is an inbuilt application programming interface of fs module which is used to read the file and return its content. In fs. readFile() method, we can read a file in a non-blocking asynchronous way, but in fs. readFileSync() method, we can read files in a synchronous way, i.e. we are telling node.

How do you write data in a CSV file using node JS?

First, we import the native file system module ( fs ) and the csv-parse module. Then, we create a parser which accepts an object literal, containing the options we'd like to set. The second argument is the callback function that's used to access the records - or just print them out, in our case.


2 Answers

This answer provides legacy code that uses async library. Promise-based control flow with async doesn't need this library. Asynchronous processing with async.eachSeries doesn't serve a good purpose inside csv-parse callback because a callback waits for data to be filled with all collected data.

If reading all data into memory is not an issue, CSV stream can be converted to a promise:

const fs = require('fs');
const getStream = require('get-stream');
const parse = require('csv-parse');

readCSVData = async (filePath): Promise<any> => {
  const parseStream = parse({delimiter: ','});
  const data = await getStream.array(fs.createReadStream(filePath).pipe(parseStream));
  return data.map(line => line.join(',')).join('\n');
}
like image 70
Estus Flask Avatar answered Sep 18 '22 11:09

Estus Flask


My best workaround for this task is:

const csv = require('csvtojson')
const csvFilePath = 'data.csv'
const array = await csv().fromFile(csvFilePath);
like image 25
HMagdy Avatar answered Sep 22 '22 11:09

HMagdy