revup88
revup88

Reputation: 65

Fixing error: Cannot read property 'path' of undefined

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

Answers (2)

KeitelDOG
KeitelDOG

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:

  1. you really upload a file correctly

  2. 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

app_zone
app_zone

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

Related Questions