taylorbell.com

Reading a CSV File in Node.js

There's probably a better way to do this, but this is my go-to way to read a CSV file in Node.js.

First install read-csv-json:

yarn add read-csv-json

Then add it to the top of your .js file. I also like to create a variable for the file path.

const csvModule = require('read-csv-json')

const filePath = `./the_file.csv`

Now we need a list of fields that correspond to the column headers.

My cool hack here is using a vim macro to generate the fields array.

Vim Macro Sidetrack

Open the csv file. yy to yank the first line.

V (I say "shift + v" in my head instead of "capital V" for some reason) to do a visual selection on the line.

:s/,/",\r/g to replace each comma with ", and a new line.

Use ctrl + v to switch to column select mode, and select each line with a column header.

Hit shift + i (capital I, yeah) to enter Column Insert mode. Type a single " and hit escape to add the quote in front of each word.

Hit gv to reselect your column, and hit > to indent.

Move up a line from the first header to declare the array, and close it out at the bottom:

const headers = [
  "firstItem",
  "lastItem"
]

You can do qa to start recording a macro into register a before running these operations, and then q again when done. Now the next time you have to make a list of headers, you can just do @a and it will do the formatting for you.

vim is cool.

Back to CSV Reading

With the headers array declared, we'll instantiate a new csv module:

const csvRead = new csvModule(filePath, headers)

Now we'll write an async function called readFile. Inside of it, we'll await the JSON from the CSV file:

async function readFile() {
  const csvJSON = await csvRead.getCSVJson()
  
  return csvJSON
}

We can now call readFile(), and chain on a .then() that will contain our csvJSON file:

readFile().then(csvJSON => {
  console.log(csvJSON)  
})

Rad.

Dealing with Numbers

There's a good chance you'll have numeric data in the CSV file that you're reading. But when the JSON is created, it's going to make everything a string.

I typically just .map() over the JSON and parse ints and floats appropriately.

This is a good time for you to drop unneeded columns as well if you want.

csvJSON.map(item => {
  return {
    someNumber: parseInt(item.someNumber),
    otherNumber: parseFloat(item.otherNumber)
  }  
})