Render Image Stored in Mongo (GridFS) with Node + Jade + Express Render Image Stored in Mongo (GridFS) with Node + Jade + Express mongodb mongodb

Render Image Stored in Mongo (GridFS) with Node + Jade + Express


I figured this out (thanks Timothy!). The problem was my understanding of all these technologies and how they fit together. For anyone else who's interested in displaying images from MongoDB GridFS using Node, Express and Jade ...

My Document in MongoDB has a reference to the Image stored in GridFS which is an ObjectId stored asa string. e.g. MyEntity {ImageId:'4f6d39ab519b481eb4a5cf52'} <-- NB: String representation of ObjectId. The reason I stored it as a string was because storing the ObjectId was giving me a painin the Routing as it was rendering as binary and I couldn't figure out how to fix this. (Maybe someone can help here?). Anyway, the solution I have is below:

FileRepository - Retrieve the image from GridFS, I pass in a String Id, which I then convert toa BSON ObjectId (you can also get the file by file name):

FileRepository.prototype.getFile = function(callback,id) {   var gs = new GridStore(this.db,new ObjectID(id), 'r');   gs.open(function(err,gs){      gs.read(callback);   }); };

Jade Template - Render the HTML Markup:

img(src='/data/#{myentity.ImageId}')

App.JS file - Routing (using Express) I setup the '/data/:imgtag' route for dynamic images:

app.get('/data/:imgtag', function(req, res) {  fileRepository.getFile( function(error,data) {     res.writeHead('200', {'Content-Type': 'image/png'});     res.end(data,'binary');  }, req.params.imgtag );});

And that did the job. Any questions let me know :)


I'm a little confused about what you're trying to do here, as Jade is a condesed markup language for text output (such as HTML), not binary content.

Since you're using Jade you probably have something like this:

app.get/'images/:imgtag', function(req, res) {    res.render('image', {imgtag: req.params.imgtag);});

So try this:

app.get/'images/:imgtag', function(req, res) {    filerep.getFile( function(imgdata) {        res.header({'Content_type': 'image/jpeg'})        res.end(imgdata);    }, req.params.imgtag );});

That will send the raw file as a response to the HTTP request with the correct mime type. If you want to use Jade to deliver a template (such as an image popup) you could use a different route for the popup or even use a data: uri and encode the image data in the page.