Search code examples
javascriptstreambusboy

FileStream from busboy to MongoDB


So I have an incoming FileStream from busboy that I want to save to MongoDB. I think I need to have it as a File or some sort of buffer to be able to save it. I'm sure I could do it by first saving it to disk using fs and then reading it, but that seems cumbersome. This is my full route code so far:

// Upload a new study plan
router.route("/add").post((req, res, next) => {
    let busboy = new Busboy({headers: req.headers});

    // A field was recieved
    busboy.on('field', function (fieldname, val, valTruncated, keyTruncated) {

        if (req.body.hasOwnProperty(fieldname)) { // Handle arrays
            if (Array.isArray(req.body[fieldname])) {
                req.body[fieldname].push(val);
            } else {
                req.body[fieldname] = [req.body[fieldname], val];
            }
        } else { // Else, add field and value to body
            req.body[fieldname] = val;
        }
    });

    // A file was recieved
    busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
        const saveTo = path.join('.', filename);
        let readFile = null;

        file.on("data", () => {
            console.log("Got file data!");
        })

        file.on("end", () => {
            //How do I save the file to MongoDB?
        })
    });

    // We're done here boys!
    busboy.on('finish', function () {
        //console.log(req.body);
        console.log('Upload complete');
        res.end("That's all folks!");
    });
    return req.pipe(busboy);
});

I want to append {"pdf": file} to my req.body which has the rest of the data...


Solution

  • So while Michal's answer is probably not wrong, it was not what I was after. I finally found a solution by using the Buffer object. Here is my code:

    router.route("/add").post((req, res, next) => {
        let busboy = new Busboy({headers: req.headers});
        let buffers = [];
    
        // A field was recieved
        busboy.on('field', function (fieldname, val, valTruncated, keyTruncated) {
    
            if (req.body.hasOwnProperty(fieldname)) { // Handle arrays
                if (Array.isArray(req.body[fieldname])) {
                    req.body[fieldname].push(val);
                } else {
                    req.body[fieldname] = [req.body[fieldname], val];
                }
            } else { // Else, add field and value to body
                req.body[fieldname] = val;
            }
        });
    
        // A file was recieved
        busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
    
            file.on("data", (data) => {
                buffers.push(data);
            });
    
            file.on("end", () => {
                req.body[fieldname] = Buffer.concat(buffers);
            });
        });
    
        // We're done here boys!
        busboy.on('finish', function () {
            console.log(req.body);
    
            const plan = new StudyPlan(req.body);
            plan.save()
                .then(_ => console.log("YEEAEH!"))
                .catch(err => {console.log(err);});
    
            res.end();
        });
        return req.pipe(busboy);
    });