How to use 'this' context in middleware

2.9k Views Asked by At

I wrote my own middleware as module for my purposes that looks like the following:

-- myMiddleware.js

module.exports = {
    fn1: function (req, res, next) {
       console.log('fn1');
       next();
    },

    fn2: function (req, res, next) {
        console.log('fn2');
        this.fn1(req, res, function () {
             next();
        });
    }
};

In my sserver.js I use this middleware as the following:

app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));

app.use(require('./myMiddleware').fn2);

Unfortunately that does not work because this context in fn2 in not myMiddleware.js object. How can use proper this?

2

There are 2 best solutions below

2
On BEST ANSWER

You can't, the 'this' property will always be the vanilla Server (http.Server) instance or compatible handler.

You can do this:

var middlewares = {};

module.exports = middlewares;

middlewares.fn1 = function(req, res, next){ ... };

middlewares.fn2 = function(req, res, next){ 
    middlewares.fn1(req, res, next); 
};
1
On

This is not because middlewares.
Always when a function is passed as an arguments in javascript it's losing the context. Express pass the middlewares around as an arguments. So that's why.

There are several techniques to bind the context, You can use apply, call, a closure, or the easier new ES6 arrow functions. This is an example using a closure:
[edit] fixing typos from your example, and adding functional code example.

middle.js

module.exports = {
    fn1: function(req, res, next) {
       console.log('fn1');
       next();
    },

    fn2: function(req, res, next) {
        var self = this;
        return function (req, res, next) {
            console.log('fn2');
            self.fn1(req, res, function () {
                next();
            });
        }
     }
};

sever.js (notice the fn2() )

var express = require('express');
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'jade');
app.use(express.favicon());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));

app.use(require('./middle.js').fn2());
app.get('/', function(req, res) {
    res.send('hey!');
});
app.listen('3000');

Googling for "javascritp function bind context" you can find good articles and understand better this behaviour.