I'm trying to stream file uploads directly to Mongo. It seems like gridform (https://github.com/aheckmann/gridform) is a great solution for this.
I am already using the express framework and love what it's doing so want to keep using it, however the usage examples for gridform seem to be based on a native http server without express.
I found that the express.bodyParser() conflicts with gridform, so instead of:
app.use(express.bodyParser()); I'm using app.use(express.json()); app.use(express.urlencoded());
That part that's confusing me though is how I now use gridform within my route. app.post('/data/AddPropertyImage', db.addPropertyImage);
exports.addPropertyImage = function(req, res){ ??? }
Try as I might I can't seem to get a valid instance from var form = gridform(); this assertion keeps failing. assert(form instanceof formidable.IncomingForm);
This is the full code seg.
exports.addPropertyImage = function(req, res){
var mongo = require('mongodb')
var formidable = require('formidable');
var assert = require('assert');
var Db = require('mongodb').Db;
var Server = require('mongodb').Server;
var MongoDb = new Db('test', new Server('localhost', 27017), {w: 1});
MongoDb.open(function(err, db) {
var gridform = require('gridform');
gridform.db = db;
gridform.mongo = mongo;
var form = gridform();
// returns a custom IncomingForm
assert(form instanceof formidable.IncomingForm);
// this returns AssertionError: false == true
});
res.send('test');
};
Edit...
As stated below I needed to use the specific version of formidable var formidable = require('gridform/node_modules/formidable');
The assertion now passes but the form.parse() doesn't seem to ever trigger. So the console.log('start parse'); line below is never hit.
console.log('start');
var mongo = require('mongodb')
//var formidable = require('formidable');
var formidable = require('gridform/node_modules/formidable');
var gridfsStream = require('gridform/node_modules/gridfs-stream');
console.log(gridfsStream);
var assert = require('assert');
var Db = require('mongodb').Db;
var Server = require('mongodb').Server;
var MongoDb = new Db('test', new Server('localhost', 27017), {w: 1});
console.log('mongo open');
MongoDb.open(function(err, db) {
var gridform = require('gridform');
gridform.db = db;
gridform.mongo = mongo;
var form = gridform();
// returns a custom IncomingForm
assert(form instanceof formidable.IncomingForm);
// this returns AssertionError: false == true
console.log('assert passed');
// optionally store per-file metadata
form.on('fileBegin', function (name, file) {
console.log('mmmeta');
file.metadata = 'so meta'
})
// parse normally
form.parse(req, function (err, fields, files) {
console.log('start parse');
// use files and fields as you do today
var file = files.inpFile1;
console.log(file);
file.name // the uploaded file name
file.type // file type per [mime](https://github.com/bentomas/node-mime)
file.size // uploaded file size (file length in GridFS) named "size" for compatibility
file.path // same as file.name. included for compatibility
file.lastModified // included for compatibility
// files contain additional gridfs info
file.root // the root of the files collection used in MongoDB ('fs' here means the full collection in mongo is named 'fs.files')
file.id // the ObjectId for this file
});
});
res.send('test');
gridform uses a specific version of formidable (1.0.11). When that particular version isn't already installed (the latest in the npm repo is 1.0.14), it will be installed as a dependency specific to the gridform module (in ./node_modules/gridform/node_modules/).
This means that unless you use that specific module, the assertion will fail because form will be inherited from a different module than the one that you pulled in using require('formidable').
To solve this, require the version used by gridform:
var formidable = require('gridform/node_modules/formidable');