Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save file uploads to Mongo DB using Express

Following this tutorial, I have managed to create a form with a file input that uploads files to a specified directory. That's dandy and all, but it doesn't save anything to a database and I don't have any reference to the files that were uploaded to display in a Jade template.

Here's what I'm doing:

// add new bulletin
exports.addbulletin = function(db) {
    return function(req, res) {

        var tmp_path = req.files.coverimage.path;
        // set where the file should actually exists - in this case it is in the "images" directory
        var target_path = './public/uploads/' + req.files.coverimage.name;
        // move the file from the temporary location to the intended location
        fs.rename(tmp_path, target_path, function(err) {
            if (err) throw err;
            // delete the temporary file, so that the explicitly set temporary upload dir does not get filled with unwanted files
            fs.unlink(tmp_path, function() {
                if (err) throw err;
                res.send('File uploaded to: ' + target_path + ' - ' + req.files.coverimage.size + ' bytes');
            });
        });

        // Submit to the DB
        collection.insert(req.body, function (err, data) {
            if (err) {
                res.send("There was a problem adding the information to the database.");
            }
            else {
                res.location("index");
                res.redirect("/");
            }
        });

    }
};

The second part of that is inserting the req.body (the other form fields that aren't file inputs) to a Mongo database. I would like to just tack on req.files along with where it's inserting the req.body, but that doesn't work.

My confusion kind of lies with how Mongo works too, I think. I'm no database expert, but when you "upload" an image, should the actual image file go to the database, or should just a reference (like the image name and location of it in the app) get added?

So in summary, I just want to save the uploaded image (or a reference to it) to the Mongo database so that I can then reference it in a Jade template to be displayed to the user.

For what it's worth, here's the relevant parts of the form (using Jade for templating):

form.new-bulletin(name="addbulletin", method="post", enctype="multipart/form-data", action="/addbulletin")
  input(type="file", name="coverimage")

UPDATE

I forgot to add that I'm using connect-multiparty

multipart = require("connect-multiparty"),
multiparty = multipart();
app.post("/addbulletin", multiparty, routes.addbulletin(db));
like image 236
Trevan Hetzel Avatar asked Nov 02 '22 04:11

Trevan Hetzel


1 Answers

Okay so the tutorial you are following is using the example of taking the temporary file information from the upload, and moving that file to another location.

So as it stand, you have the target_path variable in your code which shows where to find the file on disk. So if you want to store a reference, there you have it, and future reads of your mongo document will have that path information so you could access the file again.

As you have said, you probably don't want to be passing in the whole res.body but just access properties of it like this and construct your own document in which to insert/update whatever. Information on accessing info on the File is in the express documentation.

If you decide you want to put the File Content into your mongo document, then it is just a matter of reading the file content in. Here the core node documentation for File System operators may be of assistance to you. Particularly the read function.

From a MongoDB standpoint you can just add that content to any document field, it won't care and handles binary types. Provided that your size is under the 16MB BSON limitation.

Over that limit and maybe of interest to you, would be GridFS. And for reference there is this question on SO that may provide you with some insight on how to do this.

like image 125
Neil Lunn Avatar answered Nov 03 '22 18:11

Neil Lunn