0

I am reading a node.js book that is a couple of years old. There is an example that it creates a middleware from scratch, to add messages to a session variable.

This is the code from the book, the middleware

const express = require('express');
const res = express.response;

res.message = function(msg, type){
  type = type || 'info';
  var sess = this.req.session;
  sess.messages = sess.messages || [];
  sess.messages.push({ type: type, string: msg });
};

I guess the this here reffers to the res.message? If I console log the this from the function, then I get a huge ServerResponse like this :

 ServerResponse {
  domain: null,
  _events: { finish: [Function: bound resOnFinish] },
  _eventsCount: 1,
  _maxListeners: undefined,
  output: [],
  outputEncodings: [],
  outputCallbacks: [],
a lot more lines...

If I try to convert it to an anonymous arrow function, like so

res.message = (msg, type)=>{
  type = type || 'info';
  var sess = this.req.session;
  sess.messages = sess.messages || [];
  sess.messages.push({ type: type, string: msg });
};

then I get TypeError: Cannot read property 'session' of undefined

Since the this is lexically bound in arrow functions, maybe I dont need the this at all

res.message = (msg, type)=>{
  type = type || 'info';
  var sess = res.req.session;
  sess.messages = sess.messages || [];
  sess.messages.push({ type: type, string: msg });
};

and again I get TypeError: Cannot read property 'session' of undefined. If I console log the res inside the function, I get a different ServerResponse like this

ServerResponse {
  status: [Function: status],
  links: [Function],
  send: [Function: send],
  json: [Function: json],
a lot more lines

So , how can I convert the function, to an anonymous arrow function? And what's with the this? Where does it point to?

(the book is "Node.js in Action" by Mike Cantelon, Marc Harter, T.J. Holowaychuk and Nathan Rajlich, ©2014 by Manning Publications, chapter 9.1.2)

Thanks

codebot
  • 617
  • 1
  • 15
  • 37
  • No, the `this` inside of `res.message` refers to `res`. The `message` is the function itself, not the calling context of the function. – CertainPerformance May 28 '18 at 11:32
  • @CertainPerformance Cool. So, why the `var sess = res.req.session;` in my arrow function does not work? Isn't the `res` available in the arrow function? – codebot May 28 '18 at 11:35
  • Inside of that particular block, it's unknown what `res.message` refers to, from what you posted - it'll depend on how the function is called (see the links listed above) – CertainPerformance May 28 '18 at 11:37
  • With `function(msg, type)` the `this` refers to the instance of the current request on which you call `message` and not the `res` variable `const res = express.response;`, this `express.response` refers to a _template_ object used internally be express. For `(msg, type)=>{` the `this` refers to the context in which the arrow function was created, and `res` is the `const res = express.response;`, but none of them is the current response. So if you want to create a custom utility function for a server response, then you need to use `function(msg, type)` – t.niese May 28 '18 at 12:05
  • @CertainPerformance that's not true, because `message` won't be called on that `res` object. `express.response` is used by express as a _template_ object and is functions are then _applied_ to the current http response object. – t.niese May 28 '18 at 12:10
  • @t.niese Thanks, I got it now. So, there is no way to have an arrow function that reffers to the current response ? I guess you can pass the current `res` in the function, like so, when you call it inside a route : `res.message('test',res); ` And the function itself becomes `res.message = (msg, res, type)=>{ type = type || 'info'; console.log(res); var sess = res.req.session; sess.messages = sess.messages || []; sess.messages.push({ type: type, string: msg }); };`. This works. But I am exploring other alternatives also. – codebot May 28 '18 at 13:45
  • Bindig the `this` is the purpose of the arrow function, so if you don’t want that behavior then don’t use the arrow function. What is the reason why you want to use the arrow function instead of the regular one? – t.niese May 28 '18 at 15:26

0 Answers0