req.file is undefined when uploading an image through Postman - node.js

I am trying to write a code that is uploading an image (jpg / png), and the req.file in the code is undefined. I have tried to change it to req.files, and same thing.
const express=require('express');
const mongoose= require('mongoose');
const bodyparser=require('body-parser');
const cookieParser=require('cookie-parser');
const multer = require("multer");
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, './public/uploads')
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
})
const fileFilter = (req, file, cb)=>{
if(file.mimetype === 'image/jpg' || file.mimetype === 'image/png'){
cb(null,true);
}else{
cb(null,false);
}
}
const upload = multer({
storage:storage,
fileFilter:fileFilter
});
app.post('/api/uploadPicture', upload.single('picture'), (req, res) => {
console.log(req.files);
if(req.file) {
const pathName = req.file.path;
res.send(req.file,pathName);
}
else throw 'error';
});
Any ideas? Why is that happening ?

Related

uploads folder as static using express not working

NOTE: I have tried and seen other similar issues but none resolved my problem thus posting again, thanks.
Hey everyone! I am trying to access the images uploaded in a folder at the backend/uploads directory which is marked as static but its not working as expected.
uplaodRoutes.js
const path = require("path");
const express = require("express");
const multer = require("multer");
const router = express.Router();
const storage = multer.diskStorage({
destination(req, file, cb) {
cb(null, "backend/uploads/");
},
filename(req, file, cb) {
cb(
null,
`${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`
);
},
});
function checkFileType(file, cb) {
const filetypes = /jpg|jpeg|png/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (extname && mimetype) {
return cb(null, true);
} else {
cb("Images only!");
}
}
const upload = multer({
storage,
fileFilter: function (req, file, cb) {
checkFileType(file, CB);
},
});
router.post("/", upload.single("image"), (req, res) => {
req.file.size = req.file.size / 1000;
res.send(req.file);
});
module.exports = router;
server.js
app.use(
"/uploads",
express.static(path.join(path.resolve(), "backend/uploads"))
);
as we can see we cannot access it in browser.
const upload = multer({
**storage: fileStorageEngine,** add fileStorageEngine Parameter
storage: fileStorageEngine,
fileFilter: function (req, file, cb) {
**change from CB to cb**
checkFileType(file, cb);
},
});

Uploading file using multer triggers process.on('SIGINT')

When I upload file using multer nodemon restarts web server. It's fine on my local machine which is windows. It only happens when I start my server on ubuntu machine. What's the problem? My code is here below.
const path = require("path");
const multer = require("multer");
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.join(__dirname, '../public/uploads/'))
},
filename: function (req, file, cb) {
cb(null, file.originalname)
}
});
function checkFileType(file, cb) {
const filetypes = /jpeg|jpg|png|gif/;
const extname = filetypes.test(path.extname(file.originalname).toLowerCase());
const mimetype = filetypes.test(file.mimetype);
if (mimetype && extname) {
return cb(null, true);
} else {
cb('Only images! jpeg|jpg|png|gif ');
}
}
const upload = multer({
storage: storage,
limits: { fileSize: 5242880 },
fileFilter: function (_req, file, cb) {
checkFileType(file, cb);
}
});
router.route('/upload').post(protect, upload.array('banner', 12), (req, res, next) => {
console.log(req.files)
if (!req.files) {
res.status(400).json({ success: false, message: 'File not found' });
return;
}
const data = [];
const baseUrl = `THE_URL_FILE_UPLOAD`;
req.files.map((file, idx) => {
data.push({ path: baseUrl + file.originalname })
})
res.status(200).json({ success: true, data })
});

TypeError: that.getDestination is not a function

I am trying to use multer for the first time to upload images from node.js to mongodb and I was running a test code as shown below, to see if everything works, i followed the documentation and i can't seem to figure out what the issue is.
the full error is this :
TypeError: that.getDestination is not a function at DiskStorage._handleFile
const router = require("express").Router();
const multer = require("multer");
const storage = multer.diskStorage({
destination: {
function(req, file, callback) {
callback(null, "./uploads/");
},
},
filename: {
function(req, file, callback) {
callback(null, new Date.now + file.originalname);
},
},
});
const upload = multer({ storage:storage });
router.post("/images", upload.single("upload"), (req, res) => {
res.send(req.file);
});
module.exports = router;
multer({ storage:storage });
switch this for
multer({ storage });
I was in the same situation as you.
from what I understand, you want to upload a file to place it in ./upload/ with as name ${Date}${Filename}.
with the code i did i got what you wanted i hope this will help you
const router = require('express').Router();
const multer = require('multer');
const path = require('path');
// this create a path like './uploads/'
const uploadsDir = path.resolve(__dirname, 'uploads');
const storage = multer.diskStorage(
{
destination: uploadsDir,
filename: (req, file, cb) => {
cb(null, `${Date.now()}${file.originalname}`);
},
},
);
const upload = multer({ storage });
router.post("/images", upload.single("upload"), (req, res) => {
res.send(req.file);
});
module.exports = router;
if you want more info i found this in a github issue : https://github.com/expressjs/multer/issues/280
const express = require('express');
const app = express()
const multer = require('multer');
const path = require('path');
const storage = multer.diskStorage({
destination : (req,file,cb)=>{
cb(null,"./Uploads/")
},
filename : (req,file,cb)=>{
const fileExt = path.extname(file.originalname);
// imp file.jpg
const fileName = file.originalname
.replace(fileExt,"")
.toLowerCase()
.split(" ")
.join("-")+"-"+Date.now();
cb(null, fileName + fileExt)
}
})
const multerObj = multer({
storage : storage, // I did (dist : storage) instead of (storage : storage) do this hope you will get your result.
limits : {fileSize : 100000000},
fileFilter : (req,file,cb)=>{
if(file.mimetype === 'image/jpg' ||
file.mimetype === "image/jpeg" ||
file.mimetype === 'immage/png' ||
file.mimetype === 'application/pdf'){
cb(null,true)
}else(
cb(new Error('Only jpg,jpeg,png file allowed.'))
)
}
});
Read the comment with code carefully and do this hope you will get your desire result.

How can i use multer with react?

I am build a web app with Node.js and React and I am trying to store some files at my backend.
For some reason i cant access to my req.path , although I configured all multer strategies.
const multer = require('multer')
const config = require('config')
const auth = require('../../middleware/auth')
const {check , validationResult } = require('express-validator');
const storage = multer.diskStorage({
destination: function(req, file , cb){
cb(null,'uploads/')
},
filename: function(req, file, cb){
cb(null, req.user.id)
}
});
const fileFilter = (req, file , cb) =>{
if(file.mimetype === 'image/jpeg' || file.mimetype === 'image/jpg' || file.mimetype === 'image/png')
cb(null,false);
else
cb(null,true);
}
my route:
router.post('/' , [auth,upload.single('image'),
[
check('status','Status is required').not().isEmpty(),
check('skills','Skills is required').not().isEmpty(),
check('gender','Gender is required').not().isEmpty()
]],
async (req,res) => {// cant access to req.file.....}
and my react form:
<div className="form-group">
<input type="text" placeholder="Choose profile image" name="profileImage" value={image}/>
<input type="file" placeholder="Upload" enctype="multipart/form-data" name="image" onChange={(e) => onChange(e)}/>
<small className="form-text">The image must not be bigger then 5MB and only JPG\JPEG\PNG types</small>
</div>
Please , what am i doing wrong?
I have used multer in my backend application and this is how I have configured it and it works properly and stores required files in server file directory.
First, installing multer
npm i multer --save
Second, initialize it at the top of required .js file
const multer = require("multer");
Now, configuring storage (storage location and filename)
const storage = multer.diskStorage({
destination: "./public/uploads/postimages/",
filename: function (req, file, cb) {
cb(
null,
file.fieldname + "-" + Date.now() + path.extname(file.originalname)
);
},
});
Init multer function, (configure own file size)
Use array if you want to upload multiple files at once, 10 is the number of files, you can modify it as needed.
const upload = multer({
storage: storage,
limits: { fileSize: 10000000000 },
}).array("image", 10);
// Use .single("image"); if you want to upload a single file.
// image is the name/key that is sent from frontend with the file(s).
If you are using array, you can create an api that stores file, which will look like this.
try {
let imagePath = "abc";
let postId = req.params.postId;
let imagesLinks = [];
await upload(req, res, (err) => {
if (err) {
console.log(err);
} else {
if (req.files == undefined) {
console.log("File not found.");
} else {
//image uploaded successfully
req.files.map(function (file) {
imagePath = "uploads/postimages/" + file.filename;
imagesLinks.push(tmp);
});
}
}
res.status(201).send(imagesLinks);
});
}
For a single file, it looks as simple as this
try {
let imagePath = "abc";
upload(req, res, (err) => {
if (err) {
res.status(300).send(err);
console.log(err);
} else {
if (req.file == undefined) {
res.status(301).send("image upload failed.");
} else {
//image uploaded successfully
imagePath = "uploads/" + req.file.filename;
storeImageLink(res, imagePath);
}
}
});
}
Look at these examples. They will be help you:
File Upload With Multer in Node.js and Express
Multer Storage:
// SET STORAGE
var storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, 'uploads')
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now())
}
})
var upload = multer({ storage: storage })
Handling File Uploads:
app.post('/uploadfile', upload.single('myFile'), (req, res, next) => {
const file = req.file
if (!file) {
const error = new Error('Please upload a file')
error.httpStatusCode = 400
return next(error)
}
res.send(file)
})
Reactjs nodejs upload image — How to upload image using reactjs and nodejs (multer)
Node.js:
const path = require("path");
const multer = require("multer");
const storage = multer.diskStorage({
destination: "./public/uploads/",
filename: function(req, file, cb){
cb(null,"IMAGE-" + Date.now() + path.extname(file.originalname));
}
});
const upload = multer({
storage: storage,
limits:{fileSize: 1000000},
}).single("myImage");
const router = express.Router();
router.post("/upload", {
upload(req, res, (err) => {
console.log("Request ---", req.body);
console.log("Request file ---", req.file);//Here you get file.
/*Now do where ever you want to do*/
if(!err)
return res.send(200).end();
});
};);

Multer fileFilter is not getting called and req.body is empty

for some reason the fileFilter on multer is not getting called.
here is my Controller (i am using express routers)
const express = require('express');
const router = express.Router();
const UploadController = require('../controllers/UploadController');
router.route('/upload').post(UploadController.upload);
module.exports = router;
and this is the controller
const multer = require('multer');
const fs = require('fs');
module.exports = {
upload: function (req, res) {
let storage = multer.diskStorage({
destination: function (req, file, cb) {
console.log('here');
const filesDir = './uploads/' + req.body.ref;
if (!fs.existsSync(filesDir)) {
fs.mkdirSync(filesDir);
}
cb(null, filesDir);
},
filename: function (req, file, cb) {
let extArray = file.mimetype.split("/");
let extension = extArray[extArray.length - 1];
cb(null, req.body.type + '-' + Date.now() + '.' + extension);
},
fileFilter : function (req, file, cb) {
if (!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)) {
return cb(new Error('Only image files are allowed!'), false);
}
cb(null, true);
}
})
const upload = multer({ storage: storage }).single('file');
upload(req, res, function (err) {
if (err instanceof multer.MulterError) {
res.send({
error: err
});
} else if (err) {
res.send({
error: err
});
}else{
res.send({
file: req.file,
body: req.body
});
}
});
}
}
I have following issues:
The fileFilter function is not even called so its not validating files
the req.body on the upload function (upload: function (req, res)) is empty it is only available in diskStorage and last upload function (upload(req, res, function (err)) so i cannot validate the body data also.
I had the same problem. the fileFilter function has to be defined inside multer, not inside the diskStorage function.
To make it a bit more readable I defined the storage and filter in variables instead of making everything inside the multer call.
// storage settings
const multerStorage = multer.diskStorage({
destination: function(req, file, next) {
next(null, './public/files');
},
filename: function(req, file, next) {
const sanitizedName = file.originalname
.replace('/[^a-z0-9\./gi', '-')
.replace('/-{2,}/g', '-')
.toLowerCase();
const name = Date.now() + '-' + sanitizedName;
// sending the file name to be stored in the database
req.body.filename = name;
next(null, name);
},
limits: {
fileSize: 25000000
}
});
// filter function
const multerFilter = function(req, file, cb) {
const ext = path.extname(file.originalname).toLowerCase();
if (ext !== '.pdf') {
cb(new Error('File must be in PDF format.'));
}
cb(null, true);
}
And then applying the storage settings and filter function to multer:
const upload = multer({
storage: multerStorage,
fileFilter: multerFilter
});

Resources