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

10,028

Solution 1

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 :)

Solution 2

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.

Share:
10,028
Click Ahead
Author by

Click Ahead

Updated on July 28, 2022

Comments

  • Click Ahead
    Click Ahead almost 2 years

    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!

  • Timothy Meade
    Timothy Meade about 12 years
    Fix the mime type or detect it from gridfs
  • Click Ahead
    Click Ahead about 12 years
    Thanks Timothy, that pointed me in the right direction. There was a very other issues I needed to address so I posted my solution below for completness.