11

From ExpressJS 4 API, I find the req.files was invalid. How to upload files use ExpressJS 4 now?

vcLwei
  • 1,927
  • 3
  • 16
  • 13

2 Answers2

24

I just had this issue after upgrading, where req.files was undefined. I fixed it by using multer.

So,

npm install multer

and then in your app.js

var multer = require('multer');
app.use(multer({ dest: './tmp/'}));

I didn't have to change anything else after that and all my old functionality worked.

MikeSmithDev
  • 15,731
  • 4
  • 58
  • 89
  • I used multer as per your recommendation and it is good . But there is no control over the uploaded file in the post route, how can I manage two different file-post urls where once, I would like to rename the file and the in the other, not rename it. This I am asking because the "rename" function is defined once and it seems that it will get applied to all file-post instances. – hussainb May 25 '14 at 12:39
  • 1
    Not sure what you mean. In my actual route where I process the files, I'm not even referencing `multer` (`multer` is just used in my `app.js`). I just use req.files[0], req.files[1], etc in my route and I use `fs.readFile` and `fs.writeFile` to move it around. From Express 3 to Express 4, none of that change for me... just added `multer` in Express 4 and all old functionality worked... You may need to post a question with code example. – MikeSmithDev May 25 '14 at 14:05
  • 1
    Well right now I am using multer with your code and I get `TypeError: multer is not a function` – Musa Haidari Oct 17 '15 at 09:55
2

express.bodyParser is not included in express 4 by default. You must install separately. See https://github.com/expressjs/body-parser

Example :

var bodyParser = require('body-parser');

var app = connect();

app.use(bodyParser());

app.use(function (req, res, next) {
  console.log(req.body) // populated!
  next();
})

There is also node-formidable

var form = new formidable.IncomingForm();

form.parse(req, function(err, fields, files) {
  res.writeHead(200, {'content-type': 'text/plain'});
  res.write('received upload:\n\n');
  res.end(util.inspect({fields: fields, files: files}));
});

return;

Here is how I did it:

form = new formidable.IncomingForm();
form.uploadDir = __dirname.getParent() + "/temp/";
form.parse(req, function(err, fields, files) {
  var newfile, path, uid, versionName;
  uid = uuid.v4();
  newfile = __dirname.getParent() + "/uploads/" + uid;
  copyFile(files.file.path, newfile, function(err) {
    if (err) {
      console.log(err);
      req.flash("error", "Oops, something went wrong! (reason: copy)");
      return res.redirect(req.url);
    }
    fs.unlink(files.file.path, function(err) {
      if (err) {
        req.flash("error", "Oops, something went wrong! (reason: deletion)");
        return res.redirect(req.url);
      }
      // done!
      // ...
    });
  });
});
Vinz243
  • 9,654
  • 10
  • 42
  • 86
  • The answer is right, use the third-part middleware. But I used is connect-multiparty.Then I can use req.files to get files. – vcLwei May 05 '14 at 07:13
  • 1
    using body parser in express 4.x is deprecated, and for [a very good reason](http://andrewkelley.me/post/do-not-use-bodyparser-with-express-js.html) – uiron Oct 11 '14 at 12:15