busboy not firing field, file event - node.js

In below code, only finish event called.
var Busboy = require('connect-busboy');
app.use(Busboy());
app.post('/fileupload', function(req, res) {
var fstream;
req.pipe(req.busboy);
req.busboy.on('error', function(err){
console.log(err);
});
req.busboy.on('field', function(fieldname, val, valTruncated, keyTruncated) {
console.log("fieldname: " + fieldname);
});
req.busboy.on('file', function (fieldname, file, filename) {
console.log("filename: " + filename);
fstream = fs.createWriteStream(__dirname + '/files/' + filename);
file.pipe(fstream);
fstream.on('close', function () {
res.redirect('back');
console.log("fileupload end");
});
});
req.busboy.on('finish', function() {
console.log('Done parsing form!');
});
});

The reason why you're not seeing any data is because you're already using the multer module which also parses multipart/form-data requests, saving files to disk. If you're not using multer and want to use busboy manually as you show in your code, you will need to remove the app.use(multer()); line.

Related

busboy not emitting field event

In the below code, I could see only the finish event emitting and not the field event.
const Busboy = require('busboy');
module.exports.controller = function(app) {
app.post('/api', function(req, res) {
var busboy = new Busboy({ headers: req.headers });
var formdata = {};
busboy.on('field', function (fieldname, val) {
console.log("fieldname : " + fieldname);
console.log("value : " + val);
formdata[fieldname] = val;
});
busboy.on('finish', function() {
res.send(formdata);
});
req.pipe(busboy);
});
};
As response, I receive {} back in postman. What could be possibly going wrong here?
I know this is long overdue, but I had this issue too and then I realized I was missing the name="" field in my HTML inputs.
Working snippet:
// handle form submissions
router.post('/submit', (req, res) => {
var busboy = new Busboy({ headers: req.headers });
busboy.on('field', function (fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
console.log('Field [' + fieldname + ']: value: ' + val);
});
busboy.on('finish', () => {
res.writeHead(303, { Connection: 'close', Location: '/' });
res.end();
});
req.pipe(busboy);
});

Store file in Firebase Storage using Cloud Functions REST API request

How do I store a file through a POST (form-data) HTTP REST request in Firebase Cloud Functions so I can handle in the cloud after the REST request and then store in a bucket linked to my project.
For example is very easy to access but storage is not, I've tried to use multiparty and busboy NodeJS libs but the problem still in that Im not able to save it in Firebase Storage.
var busboy = new Busboy({
headers: req.headers
});
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
file.on('data', function(data) {
// const object = data;
// const fileBucket = object.bucket;
// const bucket = gcs.bucket(filename);
// const tempFilePath = path.join(os.tmpdir(), filename);
console.log(data);
});
file.on('end', function() {
console.log('File [' + fieldname + '] Finished');
});
});
busboy.on('field', function(fieldname, val, fieldnameTruncated, valTruncated, encoding, mimetype) {
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
});
busboy.on('finish', function() {
console.log('Done parsing form!');
res.writeHead(200, {
Connection: 'close'
});
res.end();
});
req.pipe(busboy);
At the end I finish doing this solution and works fine
router.post('/upload', function (req, res) {
var busboy = new Busboy({headers: req.headers});
var files = 0, finished = false;
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
console.log('File [' + fieldname + ']: filename: ' + filename);
console.log("Uploading: " + filename);
++files;
var path = temp.writeFileSync(file);
var fstream = fs.createWriteStream(path);
fstream.on('finish', function () {
if (--files === 0) {
var bucket = firebase.bucket();
// Upload a local file to a new file to be created in your bucket.
bucket.upload(path+"",function (err, file) {
if (!err) {
console.log("Uploaded: " + path);
res.json({
uploaded: true,
created_at: new Date().getTime(),
filename: filename,
path: path,
mimeType: mimetype
});
}else{
console.error("err: " + err);
var error = new ErrorResponse(400);
error.errors+=err;
res.json(error);
}
});
}
});
file.pipe(fstream);
});
Easiest way to access fireabse/google cloud storage from a firebase function is to use the node js google cloud package for the service, in this case #google-cloud/storage.
Once its part of your functions' dependencies you simply start it up within your function js file:
const gcs = require('#google-cloud/storage')();
Because the function runs in the google cloud environment there is no need to provide authentication info (unless storage and functions aren't part of the same Google Cloud/Firebase projects).

How to view image in img tag

I got problem that i cant get this code to save to image in a img tag. the picture will only show the first time i enter the site, the next time i enter the site it is gone. guess its the pipe but is there a way to keep it there? have searched for days now...
this is my code to save it and get it.
router.post('/', function(req, res, next) {
var busboy = new Busboy({ headers : req.headers });
var fileId = new mongo.ObjectId();
busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
console.log('got file', filename, mimetype, encoding);
var writeStream = gfs.createWriteStream({
_id: fileId,
filename: filename,
mode: 'w',
content_type: mimetype,
});
file.pipe(writeStream);
}).on('finish', function() {
// show a link to the uploaded file
res.writeHead(200, {'content-type': 'text/html'});
res.end('blogginnlegg1');
});
req.pipe(busboy);
});
//get file?
router.get('/file/:id', function(req, res, next){
gfs.findOne({ _id: req.params.id }, function (err, file) {
if (err) return res.status(400).send(err);
if (!file) return res.status(404).send('');
res.set('Content-Type', file.contentType);
res.set('Content-Disposition', 'attachment; filename="' + file.filename + '"');
var readstream = gfs.createReadStream({
_id: file._id
});
readstream.on("error", function(err) {
console.log("Got error while processing stream " + err.message);
res.end();
});
readstream.pipe(res);
});
});

Saving multipart form data into mongo with Node, Mongoose and Express 4

I've seen allot of questions but no simple answer for this simple issue:
I have a form with few fields and 2 attachments. I want them all to be saved into a Mongo
document (without GridFS and without local filesytem). I am using connect-busboy for parsing the body.
How to I process the request to extract all the fields and the attachments and persist them into my model?
var model requrie ('../models/model);
router.post('/', function(req, res) {
var modelData = {}
req.busboy.on('file', function(fieldname, file, filename, encoding, mimetype) {
file.on('data', function(data) {
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
});
file.on('end', function() {
Here I want to get the file into the model before saving, right?
});
});
req.busboy.on('field', function(key, value, keyTruncated, valueTruncated) {
switch (key) {
case 'title':
model.title = value;
break;
// Other fields parsing here...
}
});
req.busboy.on('finish', function() {
debugger
var model = new Model(modelData);
model.save(function(err) {
res.end();
})
console.log('Done parsing form!');
})
req.pipe(req.busboy);
})
Thank you

How to remove incomplete uploaded file?

I am creating a node server to upload files using 'express','fs' and 'busboy' module. The server is working as expected but when I cancel the upload before complete, the incomplete file is stored in the filesystem. How can I remove the incomplete file?
var express = require("express"),
fs = require("fs"),
Busboy = require("busboy");
app = express();
app.listen(7000);
app.get("/", display_form);
app.post("/upload", function(req, res) {
var busboy = new Busboy({
headers: req.headers
});
busboy.on("file", function(fieldname, file, filename, encoding, mime) {
var fstream = fs.createWriteStream("./uploads/" + filename);
file.pipe(fstream);
file.on("data", function(chunk) {
console.log(chunk.length);
});
file.on("end", function() {
console("end");
});
fstream.on("close", function() {
fstream.close();
console("fstream close");
});
fstream.on("error", function() {
console("fstream error ");
});
});
busboy.on("finish", function() {
console.log("uploaded");
res.send("file uploaded");
});
busboy.on("error", function() {
console("error busboy");
});
req.pipe(busboy);
});
Thanks for your help and I finally I found a way to this problem. I added under mentioned code snippet and its working fine.
req.on("close", function(err) {
fstream.end();
fs.unlink('./uploads/' + name);
console.log("req aborted by client");
});
I don't know busboy, but you open a stream and never close it.
Why don't you exploit the stream and filename to 'finish' and 'error' and act accordingly?
Example:
busboy.on('error', function() {
fs.unlink('./uploads/' + filename);
console.log('error busboy');
}

Resources