I am trying to pass a request object from my routes to a controller which processes the uploads,
here is the route -
app.post('/upload/notes',auth.requiresApiLogin,function(req,res){
upload.file(req,res);
});
here is the controller (upload.js) code which has the exported file method
var fs = require('fs'),
uuid = require('node-uuid'),
path = require('path'),
Busboy = require('busboy');
exports.file = function(req, res) {
var busboy = new Busboy({ headers: req.headers});
busboy.on('file', function(fieldname, file, filename,transferEncoding,mimeType) {
console.log("inside upload function");
console.log(file);
});
busboy.on('field', function(fieldname, val, valTruncated,keyTruncated) {
console.log("inside field function");
console.log(fieldname);
});
busboy.on('finish',function(){
console.log('finished');
});
req.pipe(busboy);
//
// req.pipe(req.busboy);
// req.busboy.on('file', function(fieldname, file, filename,transferEncoding,mimeType) {
// var fName = uuid.v4();
// console.log(filename);
// var fileext = filename.substr(filename.lastIndexOf('.') + 1);
//
// console.log(transferEncoding);
// console.log(mimeType);
// var filepath = path.normalize(__dirname + '/../../');
// var fstream = fs.createWriteStream(filepath+'/server/uploads/'+fName+'.'+fileext);
// file.pipe(fstream);
// fstream.on('close', function () {
// res.redirect('back');
// });
// });
};
So, what i see that both the fields and the files are being logged in console but the finish event is not getting fired. What else should i try ?
You need to consume the file
stream somehow. For testing purposes you can ignore the data by adding file.resume();
inside the file event handler.
This answer might help someone who wants to consume the file...
Make sure to pass control back to express by calling next() in the finish method after consuming the file e.g.
app.use(function(req: Request, res: ServerResponse, next:any) {
let bb = new busboy({ headers: req.headers });
let fileData: any = null;
const fieldArray: any = [];
let dataLength: number;
const extractFields = (name: string, val: any, data: any) => {
if (Array.isArray(data[name])) {
data[name].push(val);
} else if (data[name]) {
data[name] = [data[name], val];
} else {
data[name] = val;
}
};
bb.on('field', function(fieldname: string, val:any, fieldnameTruncated: boolean, valTruncated: boolean, encoding: string, mimetype: string) {
// extract fields to add to req body for later processing
extractFields(fieldname, val, fieldArray);
console.log('Field [' + fieldname + ']: value: ' + val);
});
bb.on('file', function(fieldname: string, file: NodeJS.ReadableStream , filename: string, encoding: string, mimetype: string) {
file.on('data', function(data) {
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
// Process buffer to save complete file to add to the req for access later
if (fileData === null) {
fileData = data;
} else {
fileData = Buffer.concat([fileData, data]);
}
});
file.on('end', function() {
console.log('File [' + fieldname + '] Finished');
});
});
bb.on('finish', function() {
req.body = fieldArray
req.body.files = {file: fileData};
console.log('Done parsing form!');
next(); // <- Allows processing to continue and avoids request hanging
});
bb.on('close', () => {
console.log('Event closed')
});
// what does this do? Send the readable request stream to busboy which is a writeable stream. The above code dictates to the writeable
// how to respond when certain events are fired during the pipe.
req.pipe(bb);
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With