2

I am having an issue in uploading the file to pc as well as DB at same time.

I am using two different Modules in my code

  • Multer: For uploading file from front-end to PC
  • CSV-to-JSON: For converting CSV File to json in order to store that file in Database.

But, using two separate functions isn't my intention at all. So, when I tried combining both modules along with the base code, File uploading with Multer works but I want to upload that file to MongoDB which need to be solved by csv-to-json is a problem for me nothing seem's to be working.

here's is my code :

var express = require('express');
var multer = require('multer');
const csv = require('csvtojson');
// Import Mongodb
const mongoClient = require('mongodb').MongoClient,
  assert = require('assert');

var filename = null;

var storage = multer.diskStorage({
  destination: function(req, file, cb) {
    cb(null, 'uploads/')
  },
  filename: function(req, file, cb) {
    filename = Date.now() + '-' + file.originalname;
    cb(null, filename)
    console.log(filename);
  }
})

var upload = multer({
  storage: storage
})

var app = express();

app.get('/', (req, res) => {
  res.sendFile(__dirname + '/index.html');
});

app.post('/', upload.single('file-to-upload'), function(req, res, next) {

  // Mongodb Connection URL 
  const url = 'mongodb://localhost:27017/csvfilereader';

  // Use connect method to connect to the Server
  mongoClient.connect(url, (err, db) => {
    assert.equal(null, err);

    if (db) {
      console.log("Connected correctly to server");

      insertDocuments(db, function() {
        db.close();
      });
    } else {
      console.log('\n', 'Problem with connection', err)
    }

  });

  const insertDocuments = (db, callback) => {
    // Get the documents collection
    let collection = db.collection('uploaded');

    // CSV File Path
    const csvFilePath = 'uploads/' + filename;

    console.log(csvFilePath);
    /**
     * Read csv file and save every row of
     * data on mongodb database
     */
    csv()
      .fromFile(csvFilePath)
      .on('json', (jsonObj) => {
        collection.insert(jsonObj, (err, result) => {
          if (err) {
            console.log(err);
          } else {
            console.log('suceess');
            res.redirect('/');
            filename = null;
          }
        });
      })
      .on('done', (error) => {
        console.log('end')
      })
  }

});

app.listen(3200);
<!--
HTML Code that runs on Root
-->

<html lang="en">
  <head>
    <title>Simple Multer Upload Example</title>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <form action="/" enctype="multipart/form-data" method="post">
      <input type="file" name="file-to-upload">
      <input type="submit" value="Upload">
    </form>  
  </body>
</html>
Monkey D. Luffy
  • 181
  • 1
  • 3
  • 16

1 Answers1

0

You need to access the file name through the passed request from multer. Your filename variable doesn't point to any object.

req.file.filename will give access to your file that has been uploaded by multer.

UPDATED CODE:

var express = require("express");
var multer = require("multer");
const csv = require("csvtojson");
// Import Mongodb
const MongoClient = require("mongodb").MongoClient,
    assert = require("assert");

var filename = null;

var storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, "uploads/");
    },
    filename: function(req, file, cb) {
        filename = Date.now() + "-" + file.originalname;
        cb(null, filename);
    },
});

var upload = multer({
    storage: storage,
});

var app = express();

app.get("/", (req, res) => {
    res.sendFile(__dirname + "/index.html");
});

app.post("/", upload.single("file-to-upload"), function(req, res, next) {
    // Connection URL
    const url = "mongodb://localhost:27017";
    console.log("Multer", req.file.filename);
    // Database Name
    const dbName = "csvreader";

    // Create a new MongoClient
    const client = new MongoClient(url, { useNewUrlParser: true });

    // Use connect method to connect to the Server
    client.connect(function(err) {
        assert.equal(null, err);
        console.log("Connected successfully to database");

        const db = client.db(dbName);
        insertDocuments(db, function() {
            console.log("Closing connection");
            client.close();
        });
    });

    const insertDocuments = (db, callback) => {
        // Get the documents collection
        const collection = db.collection("uploaded");

        // CSV File Path
        const csvFilePath = "uploads/" + filename;

        console.log("Reading file from ", csvFilePath);
        /**
         * Read csv file and save every row of
         * data on mongodb database
         */
        csv()
            .fromFile(csvFilePath)
            .then(jsonObj => {
                console.log(jsonObj);
                collection.insert(jsonObj, (err, result) => {
                    if (err) {
                        console.log(err);
                    } else {
                        console.log("suceess");
                        res.redirect("/");
                        filename = null;
                        callback();
                    }
                });
            })
            .catch(err => {
                //error reading file
                console.log(err);
            });
    };
});

app.listen(3200, () => {
    console.log("Server working at port 3200");
});
Asghar Musani
  • 568
  • 4
  • 20
  • `filename = Date.now() + '-' + file.originalname;` this line in my code assigns filename a value same as the value of uploaded doc and it shows the same name which will be used by CSV-to-json as it needs a path of CSV Files to be uploaded. But I am not getting how to use the callback function. Can you explain ?? @asghar-musani – Monkey D. Luffy Feb 28 '19 at 10:05
  • Yeah, `req.file.filename` even exposes the same file that is just uploaded and is a good practice to use instead of exposing the variable globally. Your callback doesn't get executed because you need to use the callback in your function `insertDocuments` definition. Your `db.close()` doesn't ever get executed due to that. I have updated my answer from where you'd use the callback. To further understand callbacks read this: [What the hell is a callback?](https://codeburst.io/javascript-what-the-heck-is-a-callback-aba4da2deced) – Asghar Musani Mar 01 '19 at 11:22
  • In my system there is chances of repetition of filename so usage of `filename = Date.now() + '-' + file.originalname;` helps me to differentiate between them as it merges few date and time parameters with the filename. Also, after combining both codes, it does not connect to DB neither fetches the file (expected work of the csv-to-json module) . So, execution of callback is the next step, before that I need help in fixing this **CSV-to-JSON** module problem – Monkey D. Luffy Mar 01 '19 at 11:45
  • I have had the time to run your code and modified it. Updated the working version of the code. Know that right now I'm using latest vesions for both `mongodb` as well as `csvtojson` hence the change in `Mongodb client` – Asghar Musani Mar 02 '19 at 00:27
  • Can you provide what kind of errors that you see? Do you see the file being uploaded? What part of the code is not working? – Asghar Musani Mar 04 '19 at 16:15
  • Actually, I am not getting any error. FIle uploading with Multer is totally working fine but later on part of **insertDocuments** function where we call **csv()** does not seems to be working. @asghar-musani – Monkey D. Luffy Mar 05 '19 at 07:16
  • Well, the code I shared is working on my end. Try performing these two checks: Check if your csv file returns the obj in - `console.log(jsonObj)`. Secondly, check if your mongodb configuration is working - try pushing a simple json object here instead of your jsonObj. [Fetch Sample CSV here](https://sample-videos.com/download-sample-csv.php) – Asghar Musani Mar 05 '19 at 17:12
  • As I said. Both modules work separately. But after combining them they do not produce any error or intended result. @asghar-musani – Monkey D. Luffy Mar 07 '19 at 08:09