Multer Muti Upload Image With Express - node.js

I use React and Express for create Mutiupload Image
multer.js
const multer = require('multer');
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/')
},
filename: function (req, file, cb) {
cb(null, new Date().toISOString() + '-' + file.originalname)
}
})
const fileFilter = (req, file, cb) => {
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') {
cb(null, true)
} else {
//reject file
cb({message: 'Unsupported file format'}, false)
}
}
const upload = multer({
storage: storage,
limits: { fileSize: 1024 * 1024 },
fileFilter: fileFilter
})
module.exports = upload;
post.controller.js
async onInsert(req, res) {
try {
let result = await Service.insert(req.body)
res.success(result, 201);
} catch (error) {
res.error(error.message, error.status)
}
},
post.service.js
insert(data) {
return new Promise(async(resolve, reject) => {
try {
const obj = new Post(data)
let inserted = await obj.save()
resolve(inserted)
} catch (error) {
reject(methods.error(error.message, 400))
}
});
},
I try to implements Multer on this controller but it can't upload anyway . so how to implements mutiple upload image with this code thank
I use mongoose by the way

const fileStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'images');
},
filename: (req, file, cb) => {
cb(null, new Date().toISOString().replace(/:/g, '-') + file.originalname);
}
});
const fileFilter = (req, file, cb) => {
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpg' ||
file.mimetype === 'image/jpeg'
) {
cb(null, true);
} else {
cb(null, false);
}
};
const csrfProtection = csrf();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(
multer({ storage: fileStorage, fileFilter: fileFilter }).fields(
[
{
name: 'image1',
maxCount: 1
},
{
name: 'image',
maxCount: 1
},
{
name: 'passbook',
maxCount: 1
},
{
name:'certificate',
maxCount:1
}
]
)
);
in controller
const image=req.files.image1;
const passbook=req.files.passbook;
const certificate=req.files.passbook;
if (!image || !passbook || !certificate) {
console.log("img err");
return res.redirect('admin/');
}
const imageUrl = image[0].path;
const passbookUrl= passbook[0].path;
const certificateUrl= certificate[0].path;
this works for me but i have only used Nodejs

Related

Modify req.body after file was saved by multer

I can't figure out a simple thing. If I do pass files with the request, I want to save them, and then modify req.body a little bit inside the same multer middleware. My multer middleware:
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './uploads/')
},
filename: (req, file, cb) => {
cb(null, req.body._id + path.extname(file.originalname))
},
})
const fileFilter = (req: Request, file: Express.Multer.File, cb: multer.FileFilterCallback) => {
if (
file.mimetype === 'audio/wave' ||
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpeg'
)
return cb(null, true)
cb(null, false)
}
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 3, // up to 3 megabytes
},
fileFilter: fileFilter,
})
export const saveFiles = upload.fields([
{ name: 'audio', maxCount: 1 },
{ name: 'image', maxCount: 1 },
])
Right now I do it in the router:
if (req.files) {
if ((req as any).files.audio)
req.body.data.audio = (req as any).files.audio[0].path.replace('\\', '/')
if ((req as any).files.image)
req.body.data.image = (req as any).files.image[0].path.replace('\\', '/')
}
Which is kinda annoying, I would like to just do it inside the multer somehow before it fires next(). I just can't figure out how.
So, saveFiles is your middleware function. You don't show where you actually use it, but presumably you are registering it in your router as middleware somewhere. Because it's middleware, that means it is a function that expects to be called with the arguments (req, res, next). You can replace that next argument with your own and do your work in their like this:
// multer's middlware function, we will wrap
const saveFilesMiddleware = upload.fields([
{ name: 'audio', maxCount: 1 },
{ name: 'image', maxCount: 1 },
]);
// wrap the multer middleware with our own
export const saveFiles = function(req, res, next) {
saveFilesMiddleware(req, res, err => {
if (err) {
// upon error, just call the real next with the error
next(err);
} else {
// when no error, do our housekeeping in req.body
if (req.files) {
if ((req as any).files.audio)
req.body.data.audio = (req as any).files.audio[0].path.replace('\\', '/');
if ((req as any).files.image)
req.body.data.image = (req as any).files.image[0].path.replace('\\', '/');
}
next();
}
});
};

nodejs multer uable to create directory and upload files

I have used middleware - upload which returns error after giving both received files in log:
Error: ENOENT no such file or directory open, C:\{path here}
uploaddata.js:
const express = require("express");
const multer = require("multer");
/* const router = express.Router();
router.use(express.static(__dirname+"uploads/")); */
const Storage = multer.diskStorage({
destination: function(req, file, callback) {
console.log("file.fieldname", file);
callback(null, 'uploads/'+file.fieldname+'/');
},
filename: function(req, file, callback) {
console.log("filename::", file.originalname);
callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname);
}
});
const upload = multer({
storage: Storage,
limits: {
fileSize: 1024 * 1024
},
fileFilter: (req, file, cb) => {
checkFileType(file, cb);
}
}).fields(
[
{
name:'userpic',
maxCount:1
},
{
name:'usercv',
maxCount:1
}
]
);
function checkFileType(file, cb) {
// console.log("file.fieldname", file);
if(file.fieldname==="userpic")
{
if (file.mimetype === 'image/png' || file.mimetype === 'image/jpg' || file.mimetype === 'image/jpeg')
{ // check file type to be png, jpeg, or jpg
cb(null, true);
} else {
cb(null, false); // else fails
}
}
if(file.fieldname==="usercv")
{
if ( file.mimetype === 'application/pdf' || file.mimetype === 'application/msword' || file.mimetype === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' )
{ // check file type to be pdf, doc, or docx
cb(null, true);
} else {
cb(null, false); // else fails
}
}
}
module.exports = upload;
in console via postman I am sending image and docx file which is reading successfully but it unable to create directory and those files on server path
can any one gives me solution..

How can I convert cb error to json format in multer

I'm writing code for image upload in NodeJS using multer
My code is
var upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5
},
fileFilter: (req, file, cb) => {
if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
cb(null, true);
} else {
return cb(JSON.stringify({ "success": false, "message": "invalid mime type" }), false);
}
}
});
router.post('/upload', upload.single('image'), (req, res, next) => {
const io = req.app.get('io');
const product = new db.product({
name: req.body.name,
category: req.body.category,
image: req.protocol + "://" + req.hostname + ":" + req.socket.localPort + "/img/roundtshirt/" + req.file.filename
});
});
When I upload an invalid file from Postman, I got the following error such as my callback
<pre>{"success":false,"message":"invalid mime type"}</pre>
However, I want to convert that error to proper json format.
I've tried returning json but got an error.
You can use custom error handling from Multer here
This is my example:
const upload = multer({
storage: storage,
limits: {
fileSize: 1024 * 1024 * 5
},
fileFilter: (req, file, cb) => {
if (file.mimetype == "image/png" || file.mimetype == "image/jpg" || file.mimetype == "image/jpeg") {
cb(null, true);
} else {
return cb(new Error('Invalid mime type'));
}
}
});
const uploadSingleImage = upload.single('image');
app.post('/upload', function (req, res) {
uploadSingleImage(req, res, function (err) {
if (err) {
return res.status(400).send({ message: err.message })
}
// Everything went fine.
const file = req.file;
res.status(200).send({
filename: file.filename,
mimetype: file.mimetype,
originalname: file.originalname,
size: file.size,
fieldname: file.fieldname
})
})
})
For the full example code, please visit https://gist.github.com/huynhsamha/348722d47ee457454688698ff77fee1a
Thank for reading :D

How to define static folder path in nodejs multer image upload

I am setting static path but getting error : "Error: ENOENT: no such file or directory, open 'C:\dashboard new - Copy\uploads\2019-11-28T08:11:09.164Z1564660431900.jpg'"
const storage = multer.diskStorage({ destination: function(req, file, cb) { let dest = path.join(__dirname, '../../uploads'); cb(null, dest); }, filename: function(req, file, cb) { cb(null, new Date().toISOString() + file.originalname); }});
const fileFilter = (req, file, cb) => { if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/png') { cb(null, true); } else { cb(null, false); }};
const upload = multer({ storage: storage, limits: { fileSize: 1024 * 1024 * 5 }, fileFilter: fileFilter});
router.post("/", upload.single('productImage'), async (req, res, next) => {
try {
cosole.log('hi');
const product = new Product({
_id: new mongoose.Types.ObjectId(),
name: req.body.name,
price: req.body.price,
productImage: req.file.path
});
const saveImage = await product.save();
console.log(saveImage)
res.json(saveImage);
} catch (error) {
console.log(error);
res.json(error);
}
});
How to do this?
I think you need to provide the destination folder as a key and value, something like this(below)
var upload = multer({ dest: 'uploads/' })
You can check out the full multer documentations here
https://expressjs.com/en/resources/middleware/multer.html

How to handle errors with multer?

I need to upload images on server, but if it is not jpeg\png, or filesize > 10Mb, I need to show an error. Images uploading well, but when I am trying to upload .zip file, my console is empty, why my code can't handle an error?
var multer = require('multer');
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../public/img/avatars')
},
filename: function (req, file, cb) {
cb(null, ''+req.user._id+'')
},
fileFilter: function (req, file, cb) {
if (file.mimetype !== 'image/png' && file.mimetype !== 'image/jpg' && file.mimetype !== 'image/gif' ) {
console.log('Wrong format!');
return cb(null, false, new Error('Wrong format!'));
}
if ( file.size > 10000 ){
console.log('Too large!');
return cb(null, false, new Error('Too large!'));
}
cb(null, true);
}
});
var upload = multer({ storage: storage });
router.post('/changeAvatar', upload.single('avatar'), function(req, res) {
var id = req.user._id;
res.redirect('/user/'+id);
});
Done. Just remove fileFilter from storage function.
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, '../public/img/avatars')
},
filename: function (req, file, cb) {
cb(null, ''+req.user._id+'')
}
});
function fileFilter(req, file, cb) {
if (file.mimetype !== 'image/png' && file.mimetype !== 'image/jpg' && file.mimetype !== 'image/gif' ) {
console.log('Неправильный формат изображения!');
return cb(null, false);
}
if ( file.size > 10000 ){
console.log('Изображение весит слишком много!');
return cb(null, false);
}
cb(null, true);
}
var upload = multer({ storage: storage, fileFilter: fileFilter });

Resources