Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialShane Unger
9,401 PointsWhat did Andrew mean by the use of closures?
First off, I understand what a closure is, but I'm not sure the point he was trying to make at the very end of the video. Is he saying that any third-party function like cookieParser looks something like
const cookieParser = (() => { return (req, res, next) => { //some magic here with parsing cookies next(); } })();
?
2 Answers
Farid Wilhelm Zimmermann
16,753 PointsWhat Andrew wanted to explain was how the (req, res, next) parameters of the middleware functions, are passed down into predefined, 3rd party middleware methods such as cookieParser or bodyParser.
First lets have a look at how to include cookieParser into our express app:
const cookieParser = require('cookie-parser');
app.use(cookieParser());
As you can can see, we even though we pass cookieParser() as middleware, we don't explicity pass req, res, next parameters when invoking the method. So how do those arguments end up being used inside the cookieParser() method?
The answer is by the method being a closure.
function closure() {
return function (req, res, next) {
//Doing the actual modification of the request/response object and calling next() inside of here
console.log(req); //logs 'Here we pass our request object'
console.log(res); //logs 'Here we pass our response object'
console.log(next); //logs 'Here we pass the next() method'
}
}
let cookieParser = closure();
cookieParser('Here we pass our request object', 'Here we pass our response object', 'Here we pass the next() method')
module.exports.cookieParser = cookieParser; //export our module
In this oversimplified example, you can can see how a cookieParser() module could be developed, granted that there would be actually a lot of work to be done first, before this would parse anything!
So you might be asking yourself, why using a closure? While there are many possible reasons for this, one that everybody can directly see is that is cleans up the interface of our express application. cookieParser() just looks much cleaner than having to manually pass in the three parameters, while achieving the same result, having the req, res, next parameters downpassed automatically when being omitted in the app.use() method.
For further reading on why closures are being used so widely I refer to [https://softwareengineering.stackexchange.com/questions/203507/whats-so-useful-about-closures-in-js]
I hope that my explanation was understandable, closures are a really simple construct, whose use-cases for some weird reason tend to be really hard to grasp.
Shane Unger
9,401 Pointsconst cookieParser = (() => {
return (req, res, next) => {
//some magic here with parsing cookies
next();
}
})();
JASON LEE
17,352 PointsJASON LEE
17,352 PointsTo piggy back on Farid's example, I tried an experiments to figure out what's going on behind the scenes with the arguments passed into the function's return function.
Now the output...