Node js Multer file upload with extra text input fields - node.js

I am trying to upload a file to disk using multer. Here is my code:
const multer = require('multer');
var storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, __basedir + '/uploads/')
},
filename: (req, file, cb) => {
cb(null, file.fieldname + "-" + Date.now() + "-" + file.originalname)
}
});
var upload = multer({storage: storage});
And here goes my form to collect the file and some extra input fields
<form method="post" enctype="multipart/form-data" action="/uploadfile">
<input name="cate" type="hidden" value="<%= category %>" id="cate" name="cate"></input>
<br>
<input type="file" name="uploadfile" class="btn-success" value="Select Source">
<input type="submit" class="btn-success" ><i class="fas fa-plus"></i> Add a new Source</input>
This function uploads public/img/bg.jpg to my database, thou i would like the file to be picked by the user. How can i get the filepath string in req.files object
fs.createReadStream('public/img/bg.jpg')
.pipe(fileUpload.createWriteStream())
.on('error', function(err) {
console.log("fail");})
.on('finish', function() {
console.log("success");
});
});

Related

Error: ENOENT: no such file or directory Multer

I am getting an error in my application when I want to upload an image with Multer. I already tried to change the name and the loading address but still did not achieve anything. Any ideas ?
This is the code:
const multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb){
cb(null, path.join(__dirname,'../views/upload'));
},
filename: function(req, file, cb){
cb(null, file.fieldname + Date.now());
}
})
var upload = multer({
storage: storage
})
Route:
router.post('/user/change/image', upload.single('image'), isAuthenticated, (req, res) =>{
const file = req.file.image
if(!file) {
req.flash('error', 'Porfavor introduce un archivo valido')
} else {
res.send(file)
res.redirect('/user')
}
})
Form EJS:
<div class="tarjetaedit col-sm-6">
<form method="POST" action="/user/change/image" role="form" enctype="multipart/form-data">
<div class="form-group">
<legend class="legend">Imágen de perfil</legend>
<input type="file" class="form-control" name="image" accept="image/*">
</div>
<div class="form-group">
<button type="submit" class="btn btn-success btn-block">Subir foto</button>
</div>
</form>
</div>
Thanks to all ! I really need to fix this <3

How to check if file is being uploaded with multer

I am uploading a file using multer but the problem is as I am trying to check if it's being uploaded or not using if (req.body.file) the app will not crash but the browser will say that the page is not available. Is there another way of checking if the file will be uploaded?
var multer = require('multer');
var storage = multer.diskStorage({
//multers disk storage settings
destination: function (req, file, cb) {
cb(null, 'public/uploads/')
},
filename: function (req, file, cb) {
//var datetimestamp = Date.now();
cb(null, file.originalname)
}
});
var upload = multer({
storage: storage
})
router.post('/adduser', upload.single('image'), function (req, res) {
console.log(req.body.name);
var data = {
name: req.body.name,
password: req.body.password,
image: 'uploads/' + req.file.originalname
}
users.insert(data, function (err, data) {
console.log(data);
res.redirect('/home');
});
});
<form action="/adduser" method="post" enctype="multipart/form-data">
<input type="text" name="name" />
<input type="password" name="password" />
<input type="file" name="image" />
<input type="submit">
</form>

How can I show a progress bar of the file upload in my html

I have a file upload in node js. I want to show a line displaying upload started / upload failed / upload completed and a graphic progress bar.
How can I implement this?
Node.js:
var express = require('express');
var router = express.Router();
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './upload');
},
filename: function (req, file, cb) {
cb(null, file.originalname + '-' + Date.now());
}
});
var upload = multer({ storage : storage}).array('file', 3);
router.get('/', function(req, res){
res.send( {success: 'File uploaded!'});
})
router.post('/upload', function(req,res){
upload(req,res,function(err) {
console.log('Selected Files: ', req.files);
if(err){
res.end("Error: '" , err , "'");
}else{
console.log('Files uploaded!');
res.sendStatus(204);
}
});
});
module.exports = router;
HTML
<form enctype = "multipart/form-data"
action = "/upload"
method = "POST"
>
<input type="file" name="file"/>
<p></p>
<input type="file" name="file"/>
<p></p>
<input type="submit" value="Upload File" name="submit">
</form>
<p id="success">{{success}}</p>
Use XMLHttpRequest and .addEventListener("progress") on the client side to submit the form

Multer: how to name files after req.body parameters

I'm trying to upload a file with a form such as below
<input type="file" name="collateral" />
<input type="hidden" name="id" value="ABCDEFG" />
<input type="submit" value="Upload Image" name="submit">
and I would like to rename to file to the name in the id input (ABCDEFG). As I can't access the req.body through the rename: function(fieldname, filename), I was wondering how I would achieve this?
Try putting the file last in your POST request payload.
Then you should be able to access req.body via this callback:
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads/')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
// access req.body and rename file
}
});
var upload = multer({ storage: storage });

node.js multi file upload not working

<form action="http://localhost:3000/examples" method="post" enctype="multipart/form-data" accept="application/json">
<input type="text" name ="name">
<input type="text" name ="codedescription">
<input type="file" name ="file">
<input type="submit" value="Upload selected file to server">
</form>
var multer = require('multer');
app.use(multer({ dest: './uploads/',
onFileUploadStart : function(file){
console.log('File recieved:');
console.log(file);
},
onFileUploadData:function (file,data){
console.log('Data recieved');
},
onParseEnd: function(req,next){
next();
}
}));
app.route('/examples').post(users.requiresLogin, examples.create);
exports.create = function(req, res) {
console.log("req.files"+req.files);
console.log("req.name"+req.body.name);
console.log("req.codedescription"+req.body.codedescription);
};
Submit form without enctype="multipart/form-data" is working but I can not get files.
Submit form with enctype="multipart/form-data" is working but I can not get files as well as data.
you can try this
<html>
<head>
<title>FileUpload</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
</head>
<body>
<form id = "uploadForm"
enctype = "multipart/form-data"
action = "http://localhost:3000/api/photo"
method = "post"
>
<input type="file" name="userPhoto" multiple />
<input type="submit" value="Upload Image" name="submit" id="btnUpload">
<span id="spnStatus" />
</form>
<script>
$(document).ready(function(){
$('#btnUpload').click(function(){
$('#spnStatus').empty().text("File is Uploading");
$(this).ajaxSubmit({
error : function(xhr){
status('Error : '+xhr.status);
}
success : function(response){
$('#spnStatus').empty().text(xhr);
}
});
});
});
</script>
</body>
</html>
NodeJS Express
var express = require("../node_modules/express");
var multer = require('../node_modules/multer');
var bodyParser = require("../node_modules/body-parser");
var app = express();
app.use(bodyParser.json());
var storage = multer.diskStorage({
destination: function (req, file, callback) {
callback(null, './uploads');
},
filename: function (req, file, callback) {
callback(null, file.fieldname + '-' + Date.now());
}
});
var upload = multer({ storage : storage }).array('userPhoto',8);
app.get('/',function(req,res){
res.sendFile(__dirname + "/fileUpload.html");
});
app.post('/api/photo',function(req,res){
upload(req,res,function(err) {
if(err) {
console.log(err);
return res.end("Error uploading file.");
}
res.end("File is uploaded");
});
});
app.listen(3001,function(){
console.log("Working on port 3001");
});
Now you can upload upto 8 files at a time, if you want to upload more than eight, just edit var upload = multer({ storage : storage }).array('userPhoto','LIMITHERE');
#karthik comment, i think you need this as well including after jquery, when you want to use his example:
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery.form/3.51/jquery.form.min.js"></script>

Resources