1

I want to slightly change default expressjs behaviour of res.json(obj) method. I am trying to override it in my own middleware, the thing is I need to call its original inside.

But now it just calls itself causing a stack overflow.

app.use(function(req, res, next) {
    res.json = function(obj) {
        function delete_null_properties(obj) {
            // ...
        }
        delete_null_properties(obj);

        res.json(obj);
    };
    next();
});
CodeWizard
  • 128,036
  • 21
  • 144
  • 167
simd
  • 1,779
  • 3
  • 17
  • 23
  • Why would you want to do that? I think you are fixing the wrong problem... can you explain what you want to achieve, ie what you need to change? – Sergio Dec 06 '15 at 06:53
  • @Sergio, It shown in the code. I want the same `json`, but without null keys. I want it to be transparent inside overall application, like default approach. – simd Dec 06 '15 at 06:57
  • But `res.json` will send response back to client side... and you have a `next()` after. You are interfering with one of Expresses's response to clienth methods. I am sure you can fix you problem in another way. – Sergio Dec 06 '15 at 06:59
  • 1
    would it be anything like overriding the res.render method - http://stackoverflow.com/questions/9285880/node-js-express-js-how-to-override-intercept-res-render-function – Jaromanda X Dec 06 '15 at 07:12
  • @Sergio, why do you think interfering expresses's methods is bad? Do you think it could break functionality in modules that could strictly rely on this method? Anyway, I don't think there's much of a change to worry about in case of deleting nulls. – simd Dec 06 '15 at 07:31
  • @user3537411 why to use a framework? many smart people spent time making it as it is now so I don't see the point of changing it. I feel you are fixing the problem in the wrong moment of the logic. – Sergio Dec 06 '15 at 07:37

3 Answers3

17

I don't know the inner workings of express very well, but it seems something like this should work

app.use(function(req, res, next) {
    var json = res.json;
    res.json = function(obj) {
        function delete_null_properties(obj) {
            // ...
        }
        delete_null_properties(obj);

        json.call(this, obj);
    };
    next();
});

edit: changed json(obj) to json.call(this, obj) as per comment by user3537411 and this previous answer to a similar question

P.S. I started the answer with I don't know the inner workings of express very well to avoid the sort of comments that just put crap on an answer without really going into WHY an answer is bad ... instead I get the sort of comment that's equally pointless. You can't win with SO trolls

Community
  • 1
  • 1
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
  • Where are you calling `res.json()`? – Sergio Dec 06 '15 at 07:04
  • @JaromandaX yes, 3 wrong things in my opinion. First is that you are overriding a send method and never even calling it, you are passing a function to it and calling `next()`after it... Oh, and I'm not the one asking the question. – Sergio Dec 06 '15 at 07:08
  • @Sergio - simple mistake, I meant *THE question* - not *your question* – Jaromanda X Dec 06 '15 at 07:14
  • @JaromandaX no problem. Main part of my comment was to answer your (now deleted) comment asking what was wrong with your answer. – Sergio Dec 06 '15 at 07:17
  • @JaromandaX, thanks! Your answer would work with a little change: `var _json = res.json;` and `_json.call(this, obj);` – simd Dec 06 '15 at 07:17
  • why _json? you can use `json` ... `_` has no significance – Jaromanda X Dec 06 '15 at 07:17
  • @JaromandaX, yeah, my mistake. Than just `json.call(this, obj);` – simd Dec 06 '15 at 07:19
0

You can do like below, after const app = express(); dont use this.json and dont use this.send inside the function otherwise you will get a maximum call size error :

app.response.json = function(body: any) {
    this.contentType('json').end(JSON.stringify(
      {
          code: ApiCode.OPERATION_SUCCES,
          message: CommonMessages.OperationSuccess.message,
          data: body,
          description: CommonMessages.OperationSuccess.description
        }
    ));
    return this; 
}
De Bonheur
  • 742
  • 10
  • 13
-1

It also might be useful

https://github.com/muratcorlu/connect-api-mocker/pull/30

Mounting twice will apply only last one.

const express = require('../../node_modules/express');

const app = express();

// default response
app.use('/', (req, res, next) => {
  next();

  try {
    res.send({
      profile: {
        first_name: 'Aaron',
        last_name: 'Pol'
      }
    });
  } catch (e) {
    //
  }
});

// definite state, where default response can be changed
app.use('/', (req, res) => {
  res.send({
    profile: {
      first_name: 'John',
      last_name: 'Pol'
    }
  });
});

app.listen(9090);
OlegDovger
  • 122
  • 6