This is my storage for multer I want to name files with session username and that is where my problem lays
If I const upload outside I cannot access req.session.user.username anymore...
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./uploads/usersprofile/");
},
filename: function (req, file, cb) {
cb(
null,
file.fieldname +
"_" +
`${req.session.user.username}${path.extname(file.originalname)}`
);
},
});
This is my route to which I upload file but it uploads file but gives me "upload is not a function" error I am unsure how to make it work with if (req.session.user && req.session.user.username) {} and so it doesn't allow not logged in users to upload plus not show "upload is not a function" error
router.post(
"/uploadpicture",
multer({
storage: storage,
fileFilter: (req, file, cb) => {
if (
file.mimetype == "image/png" ||
file.mimetype == "image/jpg" ||
file.mimetype == "image/jpeg"
) {
cb(null, true);
} else {
cb(null, false);
return cb(new Error("Only .png, .jpg and .jpeg format allowed!"));
}
},
limits: { fileSize: maxSize },
}).single("avatar"),
(req, res) => {
if (req.session.user && req.session.user.username) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
res.send(err);
} else if (err) {
res.send(err);
}
});
} else {
res.json({ loggedIn: false });
}
}
);
Fixed by creating const upload that leads to "avatar" const upload = myMulter.single("avatar");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./uploads/usersprofile/");
},
filename: function (req, file, cb) {
cb(
null,
file.fieldname +
"_" +
`${req.session.user.username}${path.extname(file.originalname)}`
);
},
});
const myMulter = multer({
storage: storage,
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("Only .png, .jpg and .jpeg format allowed!"));
}
},
limits: { fileSize: maxSize },
});
const upload = myMulter.single("avatar");
router.post("/uploadpicture", (req, res) => {
if (req.session.user && req.session.user.username) {
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
res.send(err);
} else if (err) {
res.send(err);
}
});
} else {
res.json({ loggedIn: false });
}
});
Related
I am trying to upload image file via multer and I dont understand why req.file returns undefined
I have set up form encType to mulipart/form-data, input name matches with the upload.single() parameter. I have also tried to set header multipart/form-data via axios but also did not help
auth.js
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, DIR);
},
filename: (req, file, cb) => {
const fileName = file.originalname.toLowerCase().split(" ").join("-");
cb(null, Date.now() + "-" + fileName);
},
});
const upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
if (
file.mimetype == "image/png" ||
file.mimetype == "image/jpg" ||
file.mimetype == "image/jpeg"
) {
cb(null, true);
} else {
cb(null, false);
return cb(new Error("Only .png, .jpg and .jpeg format allowed!"));
}
},
});
router.post(
"/changeAvatar",
upload.single("avatar"),
userAuth,
async (req, res, next) => {
try {
console.log(req.file);
const url =
req.protocol + "://" + req.get("host") + "/public/" + req.file.filename;
const user = await User.findByIdAndUpdate(req.user.id, { image: url });
res.json({ user });
} catch (err) {
res.json({ err });
}
}
);
react form
<form
onSubmit={handlePostAvatar}
encType="multipart/form-data"
>
<input
// style={{ display: "none" }}
type="file"
name="avatar"
id="avatar"
// ref={avatarFileRef}
onChange={changeHandle}
/>
<button style={{ cursor: "pointer" }}>Save</button>
</form>
post request
const handlePostAvatar = async (e) => {
e.preventDefault();
try {
const res = await axios.post("/api/auth/changeAvatar");
console.log(res);
} catch (err) {
console.log(err);
}
};
I'm developing this server based on this tutorial, https://www.bezkoder.com/angular-12-node-js-express-mysql/ now I'm in need of add some file upload functionalities, using Multer. but each time I try to us it, I get this error:
/home/miguel/Documents/angular_projs/examples/server/node_modules/multer/lib/make-middleware.js:45
next(err)
^
TypeError: next is not a function
at done (/home/miguel/Documents/angular_projs/examples/server/node_modules/multer/lib/make-middleware.js:45:7)
when i use it here:
//File upload configuration
const maxSize = 2 * 1024 * 1024;
let storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "/resources/static/assets/uploads/");
},
filename: (req, file, cb) => {
console.log(file.originalname);
cb(null, file.originalname);
},
});
let uploadFile = multer({
storage: storage,
limits: { fileSize: maxSize },
}).single("file");
/* ---------------------------------------------------------------------------------------------------- */
//Upload Files
exports.file_upload = async (req, res) => {
let number = req.params.number;
try {
await uploadFile(req, res);
if (req.file == undefined) {
return res.status(400).send({ message: "Please upload a file!" });
}
res.status(200).send({
message: "Uploaded the file successfully: " + req.file.originalname,
});
} catch (err) {
if (err.code == "LIMIT_FILE_SIZE") {
return res.status(500).send({
message: "File size cannot be larger than 2MB!",
});
}
res.status(500).send({
message: `Could not upload the file: ${req.file.originalname}. ${err}`,
});
}
//Check if empty
//res.status(200).json({msg:`${s03}`});
};
I've checked other tutorial and it's suppose to work
Try passing in next as a parameter.
...
exports.file_upload = async (req, res, next) => {
let number = req.params.number;
try {
await uploadFile(req, res, next);
...
I'm trying to adapt my code to upload files, but I'm not getting it, I looked in the community and I didn't understand, I'm still new to this. It always falls on the error json return, do you know what it can be?
File where you have the logic
async img(request, response){
multer({
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "./Uploads")
},
filename: (req, file, cb) => {
cb(null, Date.now().toString() + '-' + file.originalname)
},
fileFilter: (req, file, cb) => {
const extensionImg = ['image/png', 'image/jpg', 'image/jpeg'].find
(formatPermitted => formatPermitted == file.mimetype)
if(extensionImg){
return cb(null, true)
}
return cb(null, false)
}
})
}).single('image')
if(request.file){
return response.status(200).json({erro: false, message: "ok"});
}else{
return response.status(400).json({erro: true, message: "error"});
}
}
File where the route is
const IncidentsController = require('./controllers/IncidentsController');
const routes = express.Router();
routes.post('/uploads', IncidentsController.img)
multer(...).single(...) returns a middleware function. That middleware function that it returns has to be actually called in order to do something.
Typically, you would define the middleware outside a request handler and then use it as middleware on one or more request handlers.
const imgMulterMiddleware = multer({
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, "./Uploads")
},
filename: (req, file, cb) => {
cb(null, Date.now().toString() + '-' + file.originalname)
},
fileFilter: (req, file, cb) => {
const extensionImg = ['image/png', 'image/jpg', 'image/jpeg'].find
(formatPermitted => formatPermitted == file.mimetype)
if(extensionImg){
return cb(null, true)
}
return cb(null, false)
}
})
}).single('image');
Then, use that middleware as needed:
routes.post('/uploads', imgMulterMiddleware, (req, res) => {
// do something with req.file here which will be set
// by the middleware if it was successful
if (req.file) {
res.json({erro: false, message: "ok"});
} else {
res.status(400).json({erro: true, message: "error"});
}
});
I have a problem with express.js and multer when I try to upload 2 valid images and 1 example pdf to validate is all images, it will upload that two images into a folder, and then it will throw the error for pdf that is an invalid format, can I somehow validate first all images and then do the upload to folder or throw the error is something is wrong here is my code
const fileStorageEngine = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, './images');
},
filename: (req, file, cb) => {
cb(null, Date.now()+ '--' +file.originalname);
}
});
const fileFilter = (req, file, cb) => {
// Reject a file
if (file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png') {
cb(null, true);
} else {
req.fileValidationError = 'File type not supported';
cb(null, false);
}
};
const upload = multer({
storage: fileStorageEngine,
limits: {
fileSize: 1024 * 1024 * 5 // Accept files to 5mb only
},
fileFilter: fileFilter
});
app.post('/multiple', upload.array('images', 3), async(req, res, next) => {
try {
console.log("POST Multiple Files: ", req.files);
if (await req.fileValidationError) {
throw new Error(req.fileValidationError);
} else {
for (let i = 0; i < req.files.length; i++) {
let storeImage = await StoreImages.create({
images: req.files[i].path
});
if (!storeImage) {
throw new Error('Sorry, something went wrong while trying to upload the image!');
}
}
res.status = 200;
res.render("index", {
success: true,
message: "Your images successfully stored!"
});
}
} catch(err) {
console.log("POST Multiple Error: ", err);
res.status = 406;
return res.render('index', {
error: true,
message: err.message
})
}
});
I want to validate all uploaded files before insert to a folder, server, etc...
I found a solution by throwing the error in cb function in fileFilter function
const fileFilter = (req, file, cb) => {
// Reject a file
if(file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png'){
cb(null, true);
}else{
cb(new Error('File type not supported'));
}
};
I am using MongoDB, nodeJS, express, multer, jimp and gridFS to upload an image. I first uploaded the image with multer then resized it with jimp then uploaded the jimp buffer to MongoDB now when I delete the multer image an error comes that the file is probably corrupt as the chunks file is not written(i don't know why but it is actually not written when I want to delete it) can any one tell how to achieve this and what is the error in my code.
here is my post route
app.post('/upload', upload.single("file"), (req, res) => {
if(req.file === undefined || req.file === 0 || req.file === ""){
res.redirect("/");
}
console.log(req.file);
filename = req.file.filename;
Jimp.read( "http://localhost:3000/image/" + req.file.filename, (err, image) => {
if (err) {
console.log(err);
}
// .then(lenna => (tpl.clone().write(imgActive)))
image
.resize(500, Jimp.AUTO)
// console.log(img);
image.getBase64(Jimp.AUTO, (error1, base64Image) => {
if(error1){
console.log(error1);
}
const image1 = new Image({
image: base64Image,
User: "Avichal",
forTest: "Hindi1"
});
image1.save(function(error){
if(error){
console.log(error);
}
})
})
})
gfs.remove({ _id: req.file.id, root: 'uploads' }, (err, gridStore) => {
if (err) {
console.log(err);
}
});
res.redirect('/');
});
here is the error:
MongoError: no chunks found for file, possibly corrupt
just a small error I have to put the remove function In the jimp read function the corrected code is:
app.post('/upload', upload.single("file"), (req, res) => {
if(req.file === undefined || req.file === 0 || req.file === ""){
res.redirect("/");
}
console.log(req.file);
filename = req.file.filename;
Jimp.read( "http://localhost:3000/image/" + req.file.filename, (err, image) => {
if (err) {
console.log(err);
}
// .then(lenna => (tpl.clone().write(imgActive)))
image
.resize(500, Jimp.AUTO)
// console.log(img);
image.getBase64(Jimp.AUTO, (error1, base64Image) => {
if(error1){
console.log(error1);
}
const image1 = new Image({
image: base64Image,
User: "Avichal",
forTest: "Hindi1"
});
image1.save(function(error){
if(error){
console.log(error);
}
})
})
gfs.remove({ _id: req.file.id, root: 'uploads' }, (err, gridStore) => {
if (err) {
console.log(err);
}
res.redirect('/');
});
})
});