I have a list of csv-files and want to parse them. For this I imported fast-csv. I tried to implement the functionality as described in another stack overflow thread.
But in my code it does not work, and I am really confused why it does not work.
I always get an empty array as output for log(data)
.
import { ParserOptionsArgs, parseFile } from '@fast-csv/parse'
import fs from 'fs'
import path from 'path'
var files: string[] = []
fs.readdirSync(inArg).forEach((file) => {
files.push(path.parse(file).name)
})
files.forEach( async(file) => {
const data: any = await readCsv(`${inArg}/${file}.csv`, { headers: true }, (row) => {})
log(data)
// here I want make some useful with the data
})
function readCsv(path: string, options: ParserOptionsArgs | undefined, rowProcessor: (arg0: any) => any) {
return new Promise((resolve) => {
const data: any = []
parseFile(path, options)
.on('data', (row: any) => {
const obj = rowProcessor(row)
if (obj) {
data.push(obj)
log(obj)
}
})
.on('end', () => {
resolve(data)
log('Done')
})
})
}
The console output:
Files: [ 'test1', 'test2', 'test3', 'test4' ]
Done
[]
Done
[]
Done
[]
Done
[]
May someone can help me out?
CodePudding user response:
Your async/await
code is fine. BUT: You are passing a rowProcessor
function of
(row) => {}
to your readCsv
. This rowProcessor
doesn't return anything. I know it's a subtle pitfall, I stumbled upon this more than once. But how it's written above, the {}
does not define an object, but an empty function body. If you really intend to return an empty object your rowProcessor
should be
(row) => { return {}; }
or
(row) => ({})
Now, as your rowprocessor doesn't return anything, in the following snippet
const obj = rowProcessor(row)
if (obj) {
data.push(obj)
log(obj)
}
obj
will of course always be undefined
thus, nothing is pushed to your data
array and hence log(data)
will log the empty array, we see.