I’m building a Node.js app with Connect/Express.js and I want to intercept the res.render(view, option) function to run some code before forwarding it on to the original render function.
app.get('/someUrl', function(req, res) { res.render = function(view, options, callback) { view = 'testViews/' + view; res.prototype.render(view, options, callback); }; res.render('index', { title: 'Hello world' }); });
It looks like a contrived example, but it does fit in an overall framework I’m building.
My knowledge of OOP and Prototypal inheritance on JavaScript is a bit weak. How would I do something like this?
Update: After some experimentation I came up with the following:
app.get('/someUrl', function(req, res) { var response = {}; response.prototype = res; response.render = function(view, opts, fn, parent, sub){ view = 'testViews/' + view; this.prototype.render(view, opts, fn, parent, sub); }; response.render('index', { title: 'Hello world' }); });
It seems to work. Not sure if it’s the best solution as I’m creating a new response wrapper object for each request, would that be a problem?
Advertisement
Answer
Old question, but found myself asking the same thing. How to intercept res render? Using express 4.0x something now.
You can use/write middleware. The concept was a bit daunting to me at first, but after some reading it made a little more sense. And just for some context for anyone else reading this, the motivation for overriding res.render was to provide global view variables. I want session
to be available in all my templates without me having to type it in every res object.
The basic middleware format is.
app.use( function( req, res, next ) { //.... next(); } );
The next param and function call are crucial to execution. next
is the callback function, to allow multiple middleware to do their thing without blocking. For a better explanation read here
This can then be used to override render logic
app.use( function( req, res, next ) { // grab reference of render var _render = res.render; // override logic res.render = function( view, options, fn ) { // do some custom logic _.extend( options, {session: true} ); // continue with original render _render.call( this, view, options, fn ); } next(); } );
I’ve tested this code, using express 3.0.6. It should work with 4.x without issue. You can also override specific URLs combos with
app.use( '/myspcificurl', function( req, res, next ) {...} );