Express 4 - chaining res.json with promise.then does not work Express 4 - chaining res.json with promise.then does not work express express

Express 4 - chaining res.json with promise.then does not work


When you pass res.json as a function, the res object gets lost and thus when json() executes, it has no object and you get the error you are seeing. You can fix that by using .bind():

employeeRouter.get("/:id", function(req, res){   Employee.findById(req.params.id).then(res.json.bind(res));});

This will make sure that the res object stays with your method when the method is executed. Using .bind() as above is essentially the same as:

employeeRouter.get("/:id", function(req, res){   Employee.findById(req.params.id).then(function(data) {       return res.json(data);   });});

In fact, .bind() actually creates a stub function like the anonymous one in the above example. It just does it for you rather than making you do it.


To further example, let's say you had two separate res objects, res1 and res2 from two separate requests.

var x = res1.json;var y = res2.json;console.log(x === y);    // true, no association with either res1 or res2 any more

This is because referencing res1.json just gets a reference to the .json method. It uses res1 to get that method (which is fetched from the res1 prototype, but one it has the method, it's just a pointer to the method and there is no longer an association with the object that contained the method. So, when you pass res.json to a function, you get no attachment to res. Then when the function you passed res.json to goes to actually call your function it calls it like this:

var z = res.json;z();

And, when z() is called, the this value inside of json ends up being undefined and there is no connection to the res object. Using .bind() creates a stub function that calls it as res.json(...) to keep the connection to the object and make sure this is set properly when the method is executed.