Reputation: 65
I'm using MERN and multer to post and get images and data. I have no issues accomplishing this within Postman, but when I run the code it compiles the following error:
TypeError: Cannot read property 'path' of undefined
at router.post (...routes\property.js:42:34)
Code:
router.post('/add', upload.single('propertyImage'), (req, res, next) => {
console.log(req.file)
const propertyImage = req.file.path;
I'm assuming that my req
call is wrong? I've attempted to change the req
to req.file
and req.body.propertyImage
but that results in a different error entirely or the same error.
What am I missing here?
Upvotes: 1
Views: 4967
Reputation: 5180
The error:
TypeError: Cannot read property 'path' of undefined
at router.post (...routes\property.js:42:34)
is saying that no file has been able to be decoded by the the server. You have to make sure of 2 things:
you really upload a file correctly
You use correct Middleware in Express to decode the file
Let's dive inside of it.
PART 1 (CLIENT) - Make sure you use the upload the file correctly. Let's say you use upload.single('propertyImage')
, then your file input must be named propertyImage
too, so that Multer know how to decode the multipart/form-data
request and separate the file from the rest of the input, because the file and inputs are merged in a special way that only special decoders like Multer can extract.
You can use the multipart/form-data
content type. Example with Axios:
var payload = {
input1: 'value1',
propertyImage: file, // file must be a file object
};
var formData = new FormData();
for (let key in payload ) {
formData.append(key, payload[key]);
}
axios({
method: 'post',
url: '/add',
headers: {
'Content-Type': 'multipart/form-data',
},
data: formData,
})
PART 2 (SERVER) - Use the decoder for parsing the inputs:
const app = express();
// Middlewares
...
app.use(express.json());
app.use(express.urlencoded({ extended: false }));// put true for nested objects/arrays inputs
...
Check your Multer setup:
const multer = require('multer');
const port = process.env.APP_PORT || 3500;
const entityStorage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'public/images');// check for correct permission
},
filename: (req, file, cb) => {
const name = 'file-' + Date.now() + '-' + file.originalname;
cb(null, name);
}
});
const upload = multer({storage: entityStorage});
Now you should be able to get the file as:
router.post('/add', upload.single('propertyImage'), (req, res, next) => {
// log the file object, file is default property name
console.log(req.file)
// rest of the inputs
console.log(req.file)
return; //cancel it
}
Upvotes: 1
Reputation: 54
you need to add
enctype = "multipart/form-data"
in the form tag of your html
something like
form(method='POST', action='/add', enctype = "multipart/form-data")
reference : https://www.npmjs.com/package/multer (see the Basic Usage)
Upvotes: 1