Upload file to Local directory as well as MongoDB - node.js

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>

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");
});

Related

How to upload and read excel file in nodejs?

I want to build an API "/upload/excel" that will allow users to import an excel file and inside it after receiving an excel file, it will read its field and save it into database.
How to achieve this?
I am using multer for uploading the file and xlsx to process it and mongodb as a database (mongoose for the model):
Lead is the data model, you have to add the Excel sheet columns name. See mongoose documentation for more information
const express = require("express");
const multer = require("multer");
const connectDB = require("./config/db");
const Lead = require("./models/Lead");
connectDB();
const uploadXLSX = async (req, res, next) => {
try {
let path = req.file.path;
var workbook = XLSX.readFile(path);
var sheet_name_list = workbook.SheetNames;
let jsonData = XLSX.utils.sheet_to_json(
workbook.Sheets[sheet_name_list[0]]
);
if (jsonData.length === 0) {
return res.status(400).json({
success: false,
message: "xml sheet has no data",
});
}
let savedData = await Lead.create(jsonData);
return res.status(201).json({
success: true,
message: savedData.length + " rows added to the database",
});
} catch (err) {
return res.status(500).json({ success: false, message: err.message });
}
};
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "uploads");
},
filename: function (req, file, cb) {
cb(null, Date.now() + "-" + file.originalname);
},
});
const upload = multer({ storage: storage });
app.post("/upload", upload.single("xlsx"), uploadXLSX);
const port = process.env.PORT || 5000;
const server = app.listen(port, () => {
console.log("app running on port", port);
});
So from here when you make a call to localhost:5000/upload with postman see picture below
You can upload a file through multer or formidable
https://www.npmjs.com/package/multer
https://www.npmjs.com/package/formidable
And you can read xl files though any one of these below npm packges
https://www.npmjs.com/package/xlsx
https://www.npmjs.com/package/read-excel-file

Unable to import csv to mongo through post method in node

i wanted to create a fronted with a input type file for uploading data to my mongodb collection. I used the below code buts its giving me the following error
Error: ENOENT: no such file or directory, open 'C:\Users\User\cogazzimport\public\uploads\fcnewimport.csv'
My Codes
app.js
...
var storage = multer.diskStorage({
destination:(req,file,cb)=>{
cb(null,'./public/uploads');
},
filename:(req,file,cb)=>{
cb(null,file.originalname);
}
});
var uploads = multer({storage:storage});
//init app
var app = express();
//set the template engine
app.set('view engine','ejs');
//fetch data from the request
app.use(bodyParser.urlencoded({extended:false}));
//static folder
app.use(express.static(path.resolve(__dirname,'public')));
var temp ;
let url = "mongodb://localhost:27017/";
app.post('/',uploads.single('csv'),(req,res)=>{
csvtojson()
.fromFile(req.file.path)
.then(csvData => {
console.log(csvData);
mongodb.connect(
url,
{ useNewUrlParser: true, useUnifiedTopology: true },
(err, client) => {
if (err) throw err;
client
.db("coggaz")
.collection("idata")
.insertMany(csvData, (err, res) => {
if (err) throw err;
console.log(`Inserted: ${res.insertedCount} rows`);
client.close();
});
}
);
});
});
//assign port
var port = process.env.PORT || 3010;
app.listen(port,()=>console.log('server run at port '+port));
index.ejs
<form action="/" method="post" enctype="multipart/form-data">
<input type="file" name="csv"><br><br>
<div class="text-center"><button type="submit" class="btn btn-lg btn-primary">submit</button></div>
</form>
I tried various solutions but still getting the same error. Any solution with a correction code would be appreciated
use this code
var storage = multer.diskStorage({
destination:(req,file,cb)=>{
cb(null,'./public/uploads');
},
filename:(req,file,cb)=>{
cb(null,file.originalname);
}
});
var uploads = multer({storage:storage});
router.post('/import_data', uploads.single('file'), async (req, res) => {
try {
// importing csv file to database
const jsonArray = await csv().fromFile(req.file.path);
const roles = await Role.insertMany(jsonArray)
await roles.save()
res.send({msg:"csv data saved successfully"})
} catch (e) {
res.send(e)
}
use this and change Schema according to your databse name

File uploads but the multer code is not executed | Node + multer + express + formdata

I am uploading a video file to a local folder using form, multer, express and nodejs.
The video file gets uploaded to the local folder - everytime I upload it through the form. However, the code inside upload executes only occasionally. Once in 5 times. i.e. console.log('33'); inside the app.post doesn't always get printed. However, console.log('1') (the one inside post and before upload) works everytime.
server.js code
var Express = require('express');
var multer = require('multer');
var mkdirp = require('mkdirp');
var app = Express();
var cors = require('cors');
app.use(cors());
var Storage = multer.diskStorage({
destination: function(req, file, cb) {
var dir = './client/public/video/';
mkdirp(dir, function(err) {
if(err) {
console.error(err);
}
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({
storage: Storage
}).single("file");
app.post("/api", function(req, res) {
console.log('1');
upload(req, res, function(err) {
console.log('33');
if (err) {
return res.end("Something went wrong!");
}
return res.status(200).end("File uploaded successfully!.");
});
});
var server = app.listen(9000, function () {
console.log('app listening at 9000');
});
app.js code
import React, { Component } from "react";
import axios from "axios";
class App extends Component {
state = {
file: null
};
handleOnChange = e => this.setState({ [e.target.name]: e.target.value });
handleOnUploadFile = e => this.setState({ file: e.target.files[0] });
handleOnSubmit = e => {
e.preventDefault();
const formData = new FormData();
formData.append("file", this.state.file);
axios
.post("http://localhost:9000/api", formData, {
headers: {
'accept': 'video/mp4',
'Accept-Language': `en-US,en;q=0.8`,
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`,
}
})
.then(res => console.log(res.data))
.catch(err => console.error(err));
};
render() {
return (
<form>
<input type="file" encType="multipart/form-data"
name="file"
accept="video/mp4"
onChange={this.handleOnUploadFile}/>
<button type="submit" className="btn btn-danger" onClick={this.handleOnSubmit}>
Submit
</button>
</form>
);
}
}
export default App;
I am new to react/node js. Tried a lot of suggestions from other posts, but couldn't find the solution.
Try adding async and await.
server.js
var Express = require('express');
var multer = require('multer');
var mkdirp = require('mkdirp');
var app = Express();
var cors = require('cors');
app.use(cors());
var Storage = multer.diskStorage({
destination: function(req, file, cb) {
var dir = './client/public/video/';
mkdirp(dir, function(err) {
if(err) {
console.error(err);
}
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({
storage: Storage
}).single("file");
app.post("/api", function(req, res) {
console.log('1');
upload(req, res, function(err) {
console.log('33');
if (err) {
return res.end("Something went wrong!");
}
return res.status(200).end("File uploaded successfully!.");
});
});
app.get("/", function(req, res) {
console.log('1');
return res.status(200).json({});
});
var server = app.listen(9900, function () {
console.log('app listening at 9900');
});
App.js
import React, { Component } from "react";
import axios from "axios";
class App extends Component {
state = {
file: null
};
handleOnChange = e => this.setState({ [e.target.name]: e.target.value });
handleOnUploadFile = e => this.setState({ file: e.target.files[0] });
handleOnSubmit = async e => {
e.preventDefault();
const formData = new FormData();
formData.append("file", this.state.file);
await axios
.post("http://localhost:9900/api", formData, {
headers: {
'accept': 'video/mp4',
'Accept-Language': `en-US,en;q=0.8`,
'Content-Type': `multipart/form-data; boundary=${formData._boundary}`,
}
})
.then(res => console.log(res.data))
.catch(err => console.error(err));
};
render() {
return (
<>
<h1>{"<b>hello</b>".bold()}</h1>
<form>
<input type="file" encType="multipart/form-data"
name="file"
accept="video/mp4"
onChange={this.handleOnUploadFile}/>
<button type="submit" className="btn btn-danger" onClick={this.handleOnSubmit}>
Submit
</button>
</form>
</>
);
}
}
export default App;
Try using a promise for your upload function:
var Express = require('express');
var multer = require('multer');
var mkdirp = require('mkdirp');
var app = Express();
var cors = require('cors');
app.use(cors());
var Storage = multer.diskStorage({
destination: function(req, file, cb) {
var dir = './client/public/video/';
mkdirp(dir, function(err) {
if(err) {
console.error(err);
}
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function(req, file, callback) {
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
var upload = multer({
storage: Storage
}).single("file");
app.post("/api", function(req, res) {
console.log('1');
upload(req, res).then((file, err) => {
console.log('33');
if (err) {
return res.end("Something went wrong!");
}
return res.status(200).end("File uploaded successfully!.");
})
});
var server = app.listen(9000, function () {
console.log('app listening at 9000');
});
Another idea would be to wrap the upload itself in a promise:
var Storage = multer.diskStorage({
return new Promise((resolve, reject) => {
destination: function(req, file, cb) {
var dir = './client/public/video/';
mkdirp(dir, function(err) {
if(err) {
reject(err)
}
cb(null, dir);
});
console.log("Upload: saved to " + dir + file.originalname);
},
filename: function(req, file, callback) {
resolve(callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);)
}
})
});

nodejs how to upload image from API

I am new to node JS and i have made function for uploading image from API.
But when i hit the URL from postman using form-data having field name image then in response it shows me.
Here is the postman image
Error uploading file
below is my code
My router.js contain:-
var express = require('express');
var router = express.Router();
var ctrlSteuern = require('../controllers/steuern.controllers.js');
router
.route('/steuern/image_upload')
.post(ctrlSteuern.imageUpload);
in Controller i have:-
var multer = require('multer');
var multiparty = require('multiparty');
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './image');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).single('image');
module.exports.imageUpload = function(req, res){
upload(req,res,function(err) {
if(err) {
return res.end("Error uploading file.");
}
return res.end("File is uploaded");
});
}
Here is my code for saving image to folder.
exports.saveMedia = (req, res) => {
const storage = multer.diskStorage({
destination: (req, file, callback) => {
callback(null, (config.const.path.base + config.const.path.productReviewMedia));
},
filename: (req, file, callback) => {
callback(null, Date.now() + '-' + file.originalname);
}
});
const upload = multer({storage: storage}).any('file');
upload(req, res, (err) => {
if (err) {
return res.status(400).send({
message: helper.getErrorMessage(err)
});
}
let results = req.files.map((file) => {
return {
mediaName: file.filename,
origMediaName: file.originalname,
mediaSource: 'http://' + req.headers.host + config.const.path.productReviewMedia + file.filename
}
});
res.status(200).json(results);
});
}
Here is post man request.

how to upload and read a file with nodejs / express

there are all kinds of posts about this, but I'm still not getting it.
I want to upload a *.csv and read and process its contents.
my jade file is this
//views/import.jade
extends layout
block content
h1= title
form(action="/import", method="post", enctype="multipart/form-data")
input(type="file", name="ufile")
input(type="submit", name="Upload")
--
I changed the code, but req.files is undefined
//routes/index.js
/* import page. */
router.get('/blah', function(req, res, next) {
res.render('import', { title: 'Import Data' });
});
router.post('/import', function(req, res) {
console.log(req.files);
});
module.exports = router;
Convert the uploaded file in to string, using
toString('utf8')
you can than make any operation on string like convert it to json using csvtojson package
Here is the sample code for uploading csv and than convert to json-
/* csv to json */
const express = require("express"),
app = express(),
upload = require("express-fileupload"),
csvtojson = require("csvtojson");
let csvData = "test";
app.use(upload());
app.get("/", (req, res, next) => {
res.sendFile(__dirname + "/index.html");
});
app.post("/file", (req, res) => {
/** convert req buffer into csv string ,
* "csvfile" is the name of my file given at name attribute in input tag */
csvData = req.files.csvfile.data.toString('utf8');
return csvtojson().fromString(csvData).then(json =>
{return res.status(201).json({csv:csvData, json:json})})
});
app.listen(process.env.PORT || 4000, function(){
console.log('Your node js server is running');
});
working example- csvjsonapi
Hope this solves your question, this is my method to multiple upload file:
Nodejs :
router.post('/upload', function(req , res) {
var multiparty = require('multiparty');
var form = new multiparty.Form();
var fs = require('fs');
form.parse(req, function(err, fields, files) {
var imgArray = files.imatges;
for (var i = 0; i < imgArray.length; i++) {
var newPath = './public/uploads/'+fields.imgName+'/';
var singleImg = imgArray[i];
newPath+= singleImg.originalFilename;
readAndWriteFile(singleImg, newPath);
}
res.send("File uploaded to: " + newPath);
});
function readAndWriteFile(singleImg, newPath) {
fs.readFile(singleImg.path , function(err,data) {
fs.writeFile(newPath,data, function(err) {
if (err) console.log('ERRRRRR!! :'+err);
console.log('Fitxer: '+singleImg.originalFilename +' - '+ newPath);
})
})
}
})
Make sure your form tag has enctype="multipart/form-data" attribute.
I hope this gives you a hand ;)

Resources