Iam using busboy body parser to parse the multipart form data. So Iam getting the fields like name, username key values in req.body and files in req.files. But Iam unable to upload files to the directory using multer.
app.use(busboyBodyParser());
app.post('/createUser', (req, res) => {
console.log(req.body);
console.log(req.files);
const storage = multer.diskStorage({
destination: './public/uploads/',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() +
path.extname(file.originalname));
}
});
const upload = multer({
storage: storage
}).single(req.files['uploadpic']);
upload(req, res, (err) => {
});
});
You don't need to use busboy with multer as it is built on top of it.
Your files are not being saved because your files come in an array form but you're trying to read it in as a single file also with a wrong syntax.
upload.single('fieldName') //is the syntax for single file
Your code will be rewritten like this:
//removing busbodyparser
//declaring multer configs
const storage = multer.diskStorage({
destination: './public/uploads/',
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now() +
path.extname(file.originalname));
}
});
const upload = multer({
storage: storage
}).array('uploadpic', 8]
//make sure you define maxCount - here 8 is given as an example
//array will take in a number of files with the same 'uploadpic' field name
app.post('/createUser', (req, res) => {
upload(req, res, function(err) {
if (err) {
//show error
}
//your files are saved and req.body and req.files are populated using multer
console.log(req.files);
console.log(req.body);
});
});
Related
I am creating userProfile in that i want to validate user details and if all data are in required format then only i want to upload the profile picture of user.
for that i created the validator middleware and then upload.single but I am getting empty array on req.body. What could be solution so that I can validate first then upload the image
code:
let uniqueSuffix;
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "public/profile_pic");
},
filename: function (req, file, cb) {
uniqueSuffix = Date.now() + "-" + file.originalname.toLocaleLowerCase();
cb(null, uniqueSuffix);
},
});
const upload = multer({ storage });
const validator = (req, res, next) => {
console.log(req.body);//logs empty array
next();
};
router.post("/signup", validator, upload.single("profile"), (req, res) => {
console.log(req.body);//i am getting whole body data here
});
you can use joi and validate req.body
I'm new in using nodejs and multer and I want to upload an image but in two different directories. I tried using two different middleware but since the first multer function returns a file destination I couldnt use it to upload in the other multer function. Is it possbile to upload a file using multer in two different directories?
Create multiple storages and call them at the same time.
Example:
const app = require("express")();
const multer = require('multer');
const storageA = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './storageA/');
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const storageB = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './storageB/');
},
filename: function (req, file, cb) {
cb(null, file.originalname);
}
});
const destA = multer({ storage: storageA });
const destB = multer({ storage: storageB });
function fileUpload(req, res, next) {
destA.single('file')(req, res, next);
destB.single('file')(req, res, next);
}
app.post("/", fileUpload, (req, res) => {
res.json({ file: req.file });
});
app.listen(3000, () => {
console.log("Server started");
});
The uploaded file will be store in ./storageA and ./storageB.
This is not an official way, but went I try it, it works!
I'm using multer as express middleware to upload a file like so:
const upload = multer().single('fieldName');
router.post(
'/',
upload,
(req, res) => {
console.log(req.file)
}
);
It works fine except when I sent the form without a file. Then apparently the upload middleware is just skipped and req.file is undefined.
I tried to add a filter like so but apparently the filter function is not called when there is no file:
function fileFilter(req, file, cb) {
console.log('filtering'); //never reached when file is missing
if (!file) {
return cb(new Error('no file', false));
}
cb(null, true);
}
const upload = multer({fileFilter: fileFilter}).single('fieldName');
router.post(...)
Is there any way to handle the missing file inside the multer middleware? Or do I have to check afterwards?
check in you html form "fieldName" in input name
and this can you help
in you routes app
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now()+'.mp3')
}
})
var upload = multer({ storage: storage })
router.post(
'/uploadfile',upload.single('fieldName'),
)
I am trying to upload an image using express but I am facing two problems, first, whenever I upload the same image again it's not getting uploaded and secondly after uploading any single image a file with image also uploading. Here is my code.
var multer = require('multer');
var uploads = multer({dest: './images'});
app.post('/uploading', uploads.single("file"), function (req, res) {
var file = __dirname +"/images" + "/" + req.file.originalname;
fs.readFile( req.file.path, function (err, data) {
fs.writeFile(file, data, function (err,data) {
if( err ){
console.error( err );
response = {
message: 'Sorry, file couldn\'t be uploaded.',
filename: req.file.originalname
};
}else{
response = {
message: 'File uploaded successfully',
filename: req.file.originalname
};
}
res.end( JSON.stringify( response ) );
});
});
})
The uploads.single("file") middleware Will handle the file upload. You don't have to specifically fs.read and fs.write the file.
var multer = require('multer');
var uploads = multer({dest: './images'});
app.post('/uploading', uploads.single("file"), function (req, res) {
//the file is uploaded automatically
})
EDIT: The above code will upload the file with hex string as filename without any extension.
In order to add rename function you need to use diskStorage. Here is the code taken from this github issue page.
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './images/')
},
filename: function (req, file, cb) {
crypto.pseudoRandomBytes(16, function (err, raw) {
cb(null, raw.toString('hex') + Date.now() + '.' + mime.extension(file.mimetype)); //this is the rename func
});
}
});
var uploads = multer({ storage: storage });
app.post('/uploading', uploads.single("file"), function (req, res) {
//the file is uploaded automatically
})
Now you can use the uploads variable as middleware as shown in the above snippet.
you can edit the filename: function (req, file, cb) { .. } according to your needs. Now the filename will be, <16characterhexstring>.ext
another way to handle it will be not using middleware and using multer manually with below options :
try {
var storage = multer.diskStorage({
destination: function(request, file, callback) {
//define folder here by fs.mkdirSync(anyDirName);
},
filename: function(req, file, callback) {
callback(null, anyFileName);
},
limits: self.limits
});
var upload = multer({
storage: storage,
fileFilter: function(request, file, callback) {
// here you can filter out what not to upload..
}
}).any();
upload(request, response, callback);
} catch (e) {
}
hope this helps!
I have uploaded files of different types(image, pptx, video and docx) using Multer in the folder named 'uploads'.
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.originalname);
}
});
var upload = multer({ //multer settings
storage: storage
}).single('file');
/** API path that will upload the files */
app.post('/upload', function(req, res) {
upload(req,res,function(err){
if(err){
res.json({error_code:1,err_desc:err});
return;
}
res.json({error_code:0,err_desc:null});
});
});
Now the uploaded files are being stored in 'uploads' folder like /uploads/demo.pptx
I need to fetch these and send the filepath or url of the stored files and send as a response to client so they can access to watch or download it.
Usually, files stored in DB when you need to do more than just serve them and upload new files. For this proposes, you could save only file's metadata to DB(such as size, type, path, name). However if you for some reason still need to store files in DB, MongoDB have GridFS component and provides a documentation about working with this component.
you can do something like this:-
var mongojs = require('mongojs');
var db = mongojs(//credential here);
var uploaded_file=db.collection("uploaded_file");
var storage = multer.diskStorage({ //multers disk storage settings
destination: function (req, file, cb) {
cb(null, './uploads/');
},
filename: function (req, file, cb) {
var datetimestamp = Date.now();
cb(null, file.originalname);
}
});
var upload = multer({ //multer settings
storage: storage
}).single('file');
/** API path that will upload the files */
app.post('/upload', function(req, res) {
upload(req,res,function(err){
if(err){
res.json({error_code:1,err_desc:err});
return;
}else{
uploaded_file.insert(res.file,function(err, saved) {// i am asuming res.file have the information you needed to send
if(err){
console.log("Unexpected error occurred during insertion in database:"+err);
}else{
res.send({error_code:0,file_info:res.file});
res.end();
}
});
}
});
});