Generalize Routes in Express Using Closures
If you’ve ever built a website using Node.js and Express then you’ve probably had to do something similar to the following snippet:
//////////////////////
// ROUTE DEFINITIONS
app.get('/', routes.index);
app.get('/landing', routes.landing);
app.get('/signin', routes.signin);
app.get('/join', routes.join);
//////////////////////////////////////
// MULTIPLE FUNCTIONS IN ROUTES FILE
exports.index = function(req, res) {
res.render('index');
}
exports.landing = function(req, res) {
res.render('landing');
}
exports.signin = function(req, res) {
res.render('signin');
}
exports.join = function(req, res) {
res.render('join');
}
So what’s wrong with this code? Too much repetition! With this method, every time a new static page is needed you have to add it in two places. Luckily, this problem can easily be solved using closures. A closure is simply a function combined with a reference environment (ie. scope).
//////////////////////
// ROUTE DEFINITIONS
app.get('/', routes.generalPage('index'));
app.get('/landing', routes.generalPage('landing'));
app.get('/signin', routes.generalPage('signin'));
app.get('/join', routes.generalPage('join'));
//////////////////////////////////////
// SINGLE FUNCTION IN ROUTES FILE
module.exports.generalPage = function(viewName) {
// Return closure containing viewName in its scope
return function(req, res) {
res.render(viewName);
};
};
The magic lies within generalPage(). When called, generalPage() returns a function that keeps reference to viewName which then can be used to render the appropriate view file. So next time you have a repetition problem in your code base, don’t forget about closures!
If you enjoyed this tutorial, please consider sponsoring my work on GitHub 🤗