Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save csv-parse output to a variable

I'm new to using csv-parse and this example from the project's github does what I need with one exception. Instead of outputting via console.log I want to store data in a variable. I've tried assigning the fs line to a variable and then returning data rather than logging it but that just returned a whole bunch of stuff I didn't understand. The end goal is to import a CSV file into SQLite.

var fs = require('fs');
var parse = require('..');

var parser = parse({delimiter: ';'}, function(err, data){
  console.log(data);
});

fs.createReadStream(__dirname+'/fs_read.csv').pipe(parser);

Here is what I have tried:

const fs = require("fs");
const parse = require("./node_modules/csv-parse");

const sqlite3 = require("sqlite3");
// const db = new sqlite3.Database("testing.sqlite");

let parser = parse({delimiter: ","}, (err, data) => {
    // console.log(data);
    return data;
});

const output = fs.createReadStream(__dirname + "/users.csv").pipe(parser);
console.log(output);
like image 480
nathanjw Avatar asked Oct 24 '25 03:10

nathanjw


1 Answers

I was also struggling to figure out how to get the data from csv-parse back to the top-level that invokes parsing. Specifically I was trying to get parser.info data at the end of processing to see if it was successful, but the solution for that can work to get the row data as well, if you need.

The key was to wrap all the stream event listeners into a Promise, and within the parser's callback resolve the Promise.

function startFileImport(myFile) {

  // THIS IS THE WRAPPER YOU NEED
  return new Promise((resolve, reject) => {

    let readStream = fs.createReadStream(myFile);

    let fileRows = [];
    const parser = parse({
      delimiter: ','
    });

    // Use the readable stream api
    parser.on('readable', function () {
      let record
      while (record = parser.read()) {
        if (record) { fileRows.push(record); }
      }
    });

    // Catch any error
    parser.on('error', function (err) {
      console.error(err.message)
    });

    parser.on('end', function () {
      const { lines } = parser.info;
      // RESOLVE OUTPUT THAT YOU WANT AT PARENT-LEVEL
      resolve({ status: 'Successfully processed lines: ', lines });
    });

    // This will wait until we know the readable stream is actually valid before piping                
    readStream.on('open', function () {
      // This just pipes the read stream to the response object (which goes to the client)
      readStream.pipe(parser);
    });

    // This catches any errors that happen while creating the readable stream (usually invalid names)
    readStream.on('error', function (err) {
      resolve({ status: null, error: 'readStream error' + err });
    });

  });
}
like image 57
sarora Avatar answered Oct 26 '25 15:10

sarora