0

My question is exactly this one. The problem is that when I apply the solution to that question, nothing happens - the value of res.send isn't logged. I use express 4.16.4.

Here's my code:

/* FILE: /app.js: */

...
const postRoute = require('./middleware/postRoute');
const myRoute = require('./routes/myRoute');
...
app.use('/', myRoute);
app.use(postRoute);
...

/* FILE: /routes/myRoute */

...
router.post('/myRoute', [], (req, res, next) => {
    res.send({ status:'success', message:'Test success. Feels good, man.' });
    next();
});
...

/* FILE: /middleware/postRoute */

const postRoute = function(req, res, next) {
    console.log('postRoute: ');
    var send = res.send;
    res.send = function(chunk, encoding){
        res.send = send;
        if (chunk) {
            console.log('postRoute chunk: ', chunk); // This statement is never reached
        }
        res.send(chunk, encoding);
    };
    next();
};
module.exports = { postRoute };

When I make a POST request to /myRoute using Postman, it logs the following: postRoute:, and that's it. The second console.log() is never reached and presumably neither is any other statement in the same function() as the console.log().

The question I link to at the start of my question was from 2015, when I assume they used a different version of Express.js, and that's why their solution isn't working for me? In my middleware code example, I used the code from a question that was linked in one of that question's answers, because it's solution didn't work for me. But that solution's obviously also not working, otherwise I wouldn't be here - and it's from 2012! Who even knows what version of Express they used back then!?

So to reiterate and conclude my question: How do I use middleware to log the value passed to res.send()?

Follow up question (but let me know if I should rather ask this in a separate question): Is there a way to call middleware after the route/response from the route instead of globally. So router.post('/myRoute', [postRoute], (req, res, next) => {...}); instead of app.use(postRoute)?

SeriousLee
  • 1,301
  • 4
  • 20
  • 42

1 Answers1

0

Here's what I ended up doing. I kept my file structure exactly the same, but instead of res.send()ing from the route, I attached the object that I would have sent, to the res object and then call next() at the end of my route. So for instance, res.send({message:'blah'}); becomes res.return = {message:'blah'}; next();. I use .return because I don't believe such a property exists on the res object by default and I find it descriptive enough for my purposes. Then in my postRoute middleware, I can easily access res.return, after which I call return res.send(res.return).

Using my example from the question (app.js stays exactly as you see it):

/* FILE: /routes/myRoute */

...
router.post('/myRoute', [], (req, res, next) => {
    if(theConditionIsMet()) {
        res.return = { message:'The condition was met.' };
    } else {
        res.return = { message:'The condition was not met.' };
    }
    next();
});
....
router.post('/anotherRoute', [], (req, res, next) => {
    // In this route I don't need to intercept the response, so I just do it like normal.
    return res.send({ message:'Feels good, man.' });
});
...

/* FILE: /middleware/postRoute */

const postRoute = function(req, res, next) {
    if(res.hasOwnProperty('return') {
        return res.send(res.return);
    }
};
module.exports = { postRoute };

One flaw I can already see is that I'll now have to restructure all my routes to use this method of res.send()ing (or at least all of the routes for which I want to intercept the return value). Because of this, and because I imagine someone more knowledgeable than me could probably figure out a better way to do it, I'm not going to accept my own answer.

SeriousLee
  • 1,301
  • 4
  • 20
  • 42