Multer: how to name files after req.body parameters - node.js

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

Related

req.file is undefined when I upload image using multer and html input form

I wanted to upload images using nodeJS and multer, so I did the following:
Below is my multer configuration:
var multer = require('multer');
var storage = multer.diskStorage({
//Setting up destination and filename for uploads
destination: function (req, file, cb) {
cb(null, 'uploads/');
},
filename: function (req, file, cb) {
cb(null, Date.now() + file.originalname);
}
});
var upload = multer({
storage: storage,
limits:{
fieldSize: 1024*1024*6,
}
});
Below is my route to upload image:
router.post('/designer', upload.single('designerImage'), async (req, res) => {
console.log(req.file);
//rest of the code which is not needed for my query
})
It works perfectly fine when I POST the file using form-data key of type file using POSTMAN. But when I try to send it using a HTML form input, req.file comes out to be undefined and no file gets uploaded to the uploads folder. Below is my HTML form code:
<form action="/designer" method="POST">
<input type="file" name="designerImage">
<form>
What is the solution to this problem? I've spend hours but couldn't get to a solution.
multer only parses multipart/form-data requests, so you need to add enctype="multipart/form-data" to your form
<form action="/designer" method="POST" enctype="multipart/form-data">
<input type="file" name="designerImage">
<form>

Multer is not saving the file as the same name and without extension?

I am using Multer to save files I upload through a form but I do not know why my code saves it as a weird name and without extension and I have just used the code from the documentation.
server.js:
const multer = require('multer');
const app = express();
var upload = multer({ dest: 'uploads/' })
app.post('/file', upload.single('filesToAttach'), function (req, res, next) {
console.log(req.file);
loadUserPage(req, res);
})
userPage.ejs:
<form action="/file" method="post" enctype="multipart/form-data">
<div id="frm-attachments">
<div>
<h3>Attachments</h3>
<div>
<input type="file" id="attachFiles" name="filesToAttach" />
<input type="submit" value="Attach">
</div>
<div id="frm-attach-files">
Attached files
<div>
<textarea id="field-attached-files" class="large-textbox" name="attached-files" spellcheck="true" rows="10" cols="50" tabindex="4" disabled="true"></textarea>
</div>
</div>
</div>
</div>
</form>
When I click on the submit button, a new file appear in the folder uploads which is supposed to have the same name and same extension as the file I uploaded in the form, but it has this name instead:
And if I try to print out(req.file), I see this:
Why is this happening? I do not even understand why they write the wrong code in the documentation...
You can set it externally,
Try this,
const multer = require('multer');
const app = express();
var storage = multer.diskStorage({
destination: 'uploads/',
filename: function(req, file, callback) {
callback(null, file.originalname);
}
});
var upload = multer({ storage: storage })
app.post('/file', upload.single('filesToAttach'), function (req, res, next) {
console.log(req.file);
loadUserPage(req, res);
})
You should make a unique name to save your file "generate a random string" and concat this this with the mimetype of your file. as you can see mimetype is already present in the req.file ,
function getFileExtension(mimeType){
if ( mimeType=== 'image/png') {
return '.png';
}
else if ( mimeType=== 'image/jpg') {
return '.jpg';
}
else if ( mimeType=== 'image/gif') {
return '.gif';
}
else {
return '.jpeg';
}
}
If you ae working on images this is the a utility function pass req.mimetype to this and concat its return value to your generated name

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>

Nodejs - req.file returns undefined

When I try to upload a file using a post method, the req.file given by multer is returned undefined.
Maybe it's not getting the correct input by name? I'm really in the dark here.
Thank you in advance for your help
//Front-end form
<form action="/dashboard" method="POST" id="newproduct-form" class="row" enctype='multipart/form-data'>
<input type="file" name="productImage" class="form-control-file" id="exampleInputFile">
</form>
//Backend
const mongoose = require('mongoose');
const multer = require('multer');
const path = require('path');
//Set Storage Engine
const storage = multer.diskStorage({
destination: './public/uploads/',
filename: function(req, file, cb){
cb(null, file.fieldname + '-' + Date.now() + path.extname(file.originalname));
}
});
//Init upload
const upload = multer({
storage: storage
}).single('productImage');
router.post('/dashboard', (req, res) => {
upload(req,res,(err) =>{
if(err) console.log(err);
console.log(req.file);
});
}
I figured it out. I was using jQuery ajax. By doing $(this).ajaxSubmit({ajax content}); instead of $.ajax({ajax content}) I managed to make it work.

Node js Multer file upload with extra text input fields

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

Resources