multer - req.file always undefined

Viewed 38275

I've looked at a lot of answer for this same question, but I haven't found a working solution yet. I am trying to make a web app that you can upload files to using express and multer, and I am having a problem that no files are being uploaded and req.file is always undefined.

My code below

'use strict';

var express = require('express');
var path    = require('path');
var multer  = require('multer')
var upload  = multer({ dest: 'uploads/' })

var app = express();
require('dotenv').load();

app.use(express.static(path.join(__dirname, 'main')));

app.post('/upload', upload.single('upl'), function (req, res, next) {
  // req.file is the `avatar` file
  // req.body will hold the text fields, if there were any
  console.log(req.file);
  res.status(204).end();
})

var port = process.env.PORT || 8080;
app.listen(port,  function () {
    console.log('Node.js listening on port ' + port + '...');
});

The form

    <form class="uploadForm" action="/upload" method="post" enctype="multipart/formdata">
        <label class="control-label">Select File</label>
        <input name="upl" id="input-1" type="file" class="file">
        <input type="submit" value="submit" />
    </form>

Help very much appreciated, this is driving me crazy.

9 Answers

Yes, your enctype is wrong and that is the only problem. Make sure that you correct your enctype otherwise you are likely to get undefined in req.file or req.files.

Hello Guys I have also wasted 24 hours and was getting same error i.e req.file is undefined. Now you can refer below code to check your solution. This is single file demo code for uploading file using multer in Node and postman. In POSTMAN Select POST method and select form-data and Key name should be 'profile'.

var express = require('express');
const app = express();
const port = 3000;
var multer = require('multer');
var upload = multer({dest:'uploads/'});
var storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, './uploads');
     },
    filename: function (req, file, cb) {
        cb(null , file.originalname);
    }
});
var upload = multer({ storage: storage })

app.post('/single', upload.single('profile'), (req, res, error) => {
    try {
      console.log(req.file);
      res.send(req.file);
    }catch(err) {
      res.send(400);
    }
  });
app.get('/', (req, res) => {
    res.send('hello Guys');
});
app.listen(port, () => {
    console.log('listening to the port: ' + port);
});

If you are using error handling as mentioned in the document, then req.file will be undefined.

An alternative way to use both error handling and to check if the file exists is to make use of express error handling:

index.js

const express = require("express");
const bodyParser = require("body-parser");
const upload = require("./upload");
const multer = require("multer");

const app = express();

app.use(bodyParser.urlencoded({ extended: true }));

app.get("/", function (req, res) {
  res.send("Hello World");
});

app.post("/upload_file", upload.single("file"), function (req, res) {
  if (!req.file) {
    throw Error("FILE_MISSING");
  } else {
    res.send("success");
  }
});

//Express Error Handling
app.use(function (err, req, res, next) {
  if (err instanceof multer.MulterError) {
    res.statusCode = 400;
    res.send(err.code);
  } else if (err) {
    if (err.message === "FILE_MISSING") {
      res.statusCode = 400;
      res.send("FILE_MISSING");
    } else {
      res.statusCode = 500;
      res.send("GENERIC_ERROR");
    }
  }
});

const server = app.listen(8081, function () {
  const port = server.address().port;

  console.log("App started at http://localhost:%s", port);
});

upload.js

const multer = require("multer");
const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, "./uploads");
  },
  filename: function (req, file, cb) {
    cb(null, Date.now() + "_" + file.originalname);
  },
});

const upload = multer({
  storage: storage,
  //   limits: { fileSize: 10 },
});

module.exports = upload;

For us this was because we were using express-http-proxy to proxy the call before multer, and we needed to use the parseReqBody: false option to properly send over the file.

ie.

app.post('file/upload', proxy(process.env.API_URL, {
  parseReqBody: false,
}))

Use:

formdata.append('file',document.getElementById("input-file").files[0]);

Instead of:

formdata.append('file',document.getElementById("input-file").files);

This is where I have done the mistake.

Related