4

I have been trying to get papaparse running on nodejs for a very long time now and I keep failing. I want to try to load my local CSV and then give this papaparse? How to do that? My code does not work.

import papa from "papaparse";
import fs from "fs";

export const convertCSV = async (res: Response) => {
  const file = await fs.createReadStream("../files/test.csv");
  papa.parse(file, {
    header: true,
    complete: function (results, file) {
      console.log("Complete", results.data.length, "records.");
    },
  });
};

results.data.length is always 0.

My CSV file is located in the files folder, which is located in the src folder:

src/files/test.csv
Lioness100
  • 8,260
  • 6
  • 18
  • 49
redlightfilms
  • 193
  • 1
  • 4
  • 13

5 Answers5

2

From the Papaparse README, it supports Node in this way:

Papa Parse can parse a Readable Stream instead of a File when used in Node.js environments (in addition to plain strings). In this mode, encoding must, if specified, be a Node-supported character encoding. The Papa.LocalChunkSize, Papa.RemoteChunkSize, download, withCredentials and worker config options are unavailable.

Papa Parse can also parse in a node streaming style which makes .pipe available. Simply pipe the Readable Stream to the stream returned from Papa.parse(Papa.NODE_STREAM_INPUT, options). The Papa.LocalChunkSize, Papa.RemoteChunkSize, download, withCredentials, worker, step and complete config options are unavailable. To register a callback with the stream to process data, use the 'data' event like so: stream.on('data', callback) and to signal the end of stream, use the 'end' event like so: stream.on('end', callback).

Erick Petrucelli
  • 14,386
  • 8
  • 64
  • 84
  • 1
    One important caveat they don't mention - do not try and use `@types/papaparse` as it will refer to all the `DOM` libraries for the calls that are not supported in node and break your build. Old school `require` works just fine. – Oly Dungey Feb 08 '23 at 15:20
2

As Erick says in their comment, the download option is not supported by Node. However, it does tell us the Node interface accepts a ReadableStream instead of a File.

This works for me:

Papa.parse(fs.createReadStream("sample/result.csv"), {
    complete: function(results) {
        console.log(results["data"]);
    }
});
Toshinou Kyouko
  • 334
  • 9
  • 21
1

Your code is fine, the problem is in the file path. fs.createReadStream needs an absolute path, or a path that's relative to the root of your project.

Assuming this is the project structure:

files/
  - test.csv
src/
  - convert-csv.ts
package.json
tsconfig.json

Then you can use a path that's relative to the root: './files/test.csv', or if you really want to use a path that's relative to the file then you can use path.resolve(__dirname, '..', 'files', 'test.csv').

See NodeJS docs for path.resolve, it will use the path segments to resolve an absolute path for you.

Nathan
  • 268
  • 2
  • 7
0

Ran into this issue with papa-parse, the docs weren't very clear. Inspired by Toshino's answer

import Papa from 'papaparse';
import { Readable } from 'stream';

export const parseCsvFromReadable = async (
  readable: Readable,
): Promise<Papa.ParseResult<unknown>> => {
  return new Promise((resolve, reject) => {
    Papa.parse(readable, {
      complete: results => {
        if (results.errors.length > 0) {
          reject(new Error(JSON.stringify(results.errors)));
        }
        resolve(results);
      },
      error: error => reject(error),
      header: true,
    });
  });
};
Colin Cheung
  • 148
  • 2
  • 13
0

To get streaming working on Nodejs on a Mac, this worked for me:

Usage: % node this-file.mjs < csv-file.csv

/* Documentation
   https://www.papaparse.com/docs#config
   https://github.com/mholt/PapaParse/blob/master/README.md#papa-parse-for-node
*/

import Papa from 'papaparse'

Papa.parse(process.stdin, {
  header: true,
  step: function(results) {
    process.stdout.write(`${JSON.stringify(results.data)}\n`)
  },
})
user1527225
  • 1,059
  • 9
  • 7