0

I want to parse a csv file coming from a react app. I have a controller which gets the csv file:

@Post(':id/transactions/upload')
  @UseInterceptors(FileInterceptor('file'))
  uploadTransactions(
    @Body() body: any,
    @UploadedFile() file: Express.Multer.File,
  ) {
    return this.accountsUsersService.uploadTransactions(file.buffer);
  }

and following service:

async uploadTransactions(buffer) {
    console.log('### buffer', buffer);
    const readBuffer = buffer.toString();
    console.log('### readBuffer', readBuffer);
    const csvData = [];
    createReadStream(buffer) // tried many tings
      .pipe(
        parse({
          delimiter: ';',
        })
        .on('data', function (dataRow) {
          csvData.push(dataRow);
        })
        .on('end', function() {
          console.log('### csvData', csvData)
        })
      )

    return 'uploaded transactions successfully';
  }

Here are the console.logs:

### buffer <Buffer 61 6c 62 65 72 74 3b 74 65 73 74 0a 6a 6f 61 6e 61 3b 67 6f 6f 64 0a>
### readBuffer albert;test
joana;good

Error: ENOENT: no such file or directory, open 'albert;test
joana;good
'

and here is the csv file:

albert;test
joana;good

Could someone clarify what am I missing?

AlbertMunichMar
  • 1,680
  • 5
  • 25
  • 49

2 Answers2

1

The issue that you're currently experiencing is explained here

It appears that the first argument of createReadStream must be a file path, if you pass a Buffer, it simply calls .toString() to it.

Jint3x
  • 21
  • 2
  • 2
  • still can't use the `createReadSTream`. In the link they say to use `const stream = Readable.from(buffer);`, but the class `Readable` has no `path` method. The issue is, the file comes from a react app as a buffer to nodejs, I don't have the path and I see no way of finding it unless creating a new brand file? – AlbertMunichMar Aug 07 '22 at 08:54
  • @AlbertMunichMar, why does the class `Readable` need to have a `path` method? If you were to use `createReadStream()` you wouldn't have a `path` method too, since both methods return a `Readable`, which from the snippet you've shown is what you need? – Jint3x Aug 07 '22 at 10:22
  • I simplified the approach, I'm learning node, so didn't know about the `FileInterceptor`. I used it, and I get the file stored in disk, and therefore I can obtain the path, pass it to the `createReadStream`, and then pipe a csv parser. – AlbertMunichMar Aug 07 '22 at 10:37
0

No need to work with the Buffer, which has no path. Using the FileInterceptor provides the file path, because you can store it in the diskStorage

@Post(':id/transactions/upload')
  @UseInterceptors(
    FileInterceptor('file', {
      storage: diskStorage({
        destination: '.files',
      }),
    }),
  )
  uploadTransactions(
    @Body() body: any,
    @UploadedFile() file: Express.Multer.File,
  ) {
    console.log('### file', file.path);
    return this.accountsUsersService.uploadTransactions(file);
  }
AlbertMunichMar
  • 1,680
  • 5
  • 25
  • 49