How can I parse data from a csv file uploaded by a user in node/express?

5.9k Views Asked by At

I have a front end react app and a backend node/express app. I want to allow a user to upload a csv file, then parse the file and instantiate a model for each row. However, I am somewhat confused about how to do this, since I am used to simply posting to a route in the API, and persisting the thing from the request body. In this case, the thing from the request body is the file, and I don't want to save the file, just the data inside it. How can I parse the file without saving it to the database? I have tried to use multer to process the upload and csv-parse to parse the contents, but I am not sure this makes sense. Nonetheless, here is the code (app/index):

               ...
const multer  = require('multer');
const upload = multer().single();
const parse = require('csv-parse'); 
               ...

router.post('/distributor/:id/files', (req,res) => { 
  upload(req, res, function (err) {
    if (err) {
      console.error("An error occurred when uploading. Please try again. Note 
      that you may only upload one file at a time, and we only support .csv 
      files.")
      return
    }
    console.log("We have received your file")
  })
});  
                         ... 

// router.get('/distributor/:id/files/:id', (req, res) => { 
//   File
//     .forge({id: req.params.id})
//     .fetch()
//     .then((file) => {
//       if (_.isEmpty(file))
//         return res.sendStatus(404);
//       return parseJson(file)
//     })
//     .then((jsonData) => { 
//       for (var i in jsonData) { 
//         //save instance of model
//       }
//     })
//     .catch((error) => {
//       console.error(error);
//       return res.sendStatus(500);
//     });
// }) 

// function parseJson(file) { 
//     var output = [];
//       // Create the parser
//     var parser = parse({delimiter: ':'});
//     // Use the writable stream api
//     parser.on('readable', function(){
//       while(record = parser.read()){
//         output.push(record);
//       }
//     });
//     // Catch any error
//     parser.on('error', function(err){
//       console.log(err.message);
//     });
//     parser.end(); 
// } 

I know this doesn't make sense, since I don't actually want to save the file as a model and table in the database, I just want to save each item inside the file, so I know I cannot make a route called '/distributor/:id/files/:id'. But I am lost as to what to do instead. I hope that what I am trying to do is clear! I am fairly new to node, and programming in general, and I have never come across a situation in which I needed to handle file upload.

1

There are 1 best solutions below

1
On

You can use this node module to parse the csv file. https://www.npmjs.com/package/csvtojson

For example you have file name users in the request object.

const csv=require('csvtojson');

csv()
.fromString(req.files.users.data.toString('utf8'))
.on('json', (user) => {
    console.log(user);
})
.on('done', () => {
    console.log('done parsing');
});

You will be able to get every row as a json object.