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

Click Ahead picture Click Ahead · Mar 23, 2012 · Viewed 9.9k times · Source

I have a small .png file stored in Mongo using GridFS. I would like to display the image in my web browser using Node + Express + Jade. I can retrieve the image fine e.g.:

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

but I don't know how to render it using the Jade View Engine. There doesn't seem to be any information in the documentation.

Can anyone point me in the right direction?

Thanks!

Answer

Click Ahead picture Click Ahead · Mar 24, 2012

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 as a 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 pain in 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 to a 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 :)