Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access Express 4 req.body object using Busboy

I need a simple way to access multipart form data in the req object using busboy-connect. I'm using Express 4, which now needs modules for previously built-in functionality.

I want the req.body object to be available in my routes, but the busboy.on('field') function is async and doesn't process all form data before passing it off to continue down the code.

There is a middleware module built on top of busboy called multer, which gets the req.body object before getting to the route, however it overrides the ability to define the busboy.on('file') event from within the route.

Here's my broken code:

// App.js

app.post(/users, function(req, res, next){

  var busboy = new Busboy({ headers: req.headers });

  // handle text field data (code taken from multer.js)
  busboy.on('field', function(fieldname, val, valTruncated, keyTruncated) {
    if (req.body.hasOwnProperty(fieldname)) {
      if (Array.isArray(req.body[fieldname])) {
        req.body[fieldname].push(val);
      } else {
        req.body[fieldname] = [req.body[fieldname], val];
      }
    } else {
      req.body[fieldname] = val;
      console.log(req.body);
    }
  });

  busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {

    tmpUploadPath = path.join(__dirname, "uploads/", filename);
    targetPath = path.join(__dirname, "userpics/", filename);

    self.imageName = filename;
    self.imageUrl = filename;

    file.pipe(fs.createWriteStream(tmpUploadPath));
  });

  req.pipe(busboy); // start piping the data.

  console.log(req.body) // outputs nothing, evaluated before busboy.on('field') 
                        // has completed.
 });

UPDATE I'm using connect-busboy. I used this middleware code in my express setup file to give me access to the req.body object within my route. I can also process the file upload from within my route and have access to the req.busbuy.on('end').

 // busboy middleware to grab req. post data for multipart submissions.
 app.use(busboy({ immediate: true }));
 app.use(function(req, res, next) {
   req.busboy.on('field', function(fieldname, val) {
     // console.log(fieldname, val);
     req.body[fieldname] = val;
   });

   req.busboy.on('finish', function(){
     next();
   });
 });
like image 894
Scott Avatar asked May 12 '14 23:05

Scott


1 Answers

Try adding:

busboy.on('finish', function() {
  // use req.body
});
like image 102
mscdex Avatar answered Oct 26 '22 03:10

mscdex