What does double parentheses mean in a require - node.js

I know what this require statement does.
var express = require('express');
var app = express();
But sometimes i have seen two parentheses after the require.
var routes = require('./routes')(app);
Q) What does this mean, and how does it work?

This is a pattern in which the module.exports of the module you are requiring is set to a function. Requiring that module returns a function, and the parentheses after the require evaluates the function with an argument.
In your example above, your ./routes/index.js file would look something like the following:
module.exports = function(app) {
app.get('/', function(req, res) {
});
// ...
};
This pattern is often used to pass variables to modules, as can bee seen above with the app variable.

Well, require is a function provided by Node.js that basically loads a module for you and it returns whatever you expose in the module that you loaded.
If what you expose (through the use of module.exports) in a given module is a function, then that is what requires returns. For instance.
//moduleX.js
module.exports = function(){
return "Helo World";
}
Then if you require it, you get a function back
var f = require('./moduleX');
console.log(f()); //hello world
Of course, you could invoke the function directly once you require it.
var greet = require('./moduleX')();
console.log(greet);

That mean that behind that, there is a function that is exported using module.exports:
module.exports = function(app) {
app.get("/", function(req, res){});
}
See also http://www.choskim.me/understanding-module-exports-and-exports-in-node-js/
Sidenote:
You could create function on the fly:
A.js
module.exports = function(data) {
return function(req, res, next) {
// Do something with data
next();
}
main.js
...
app.use(require("A")(data));
...

Related

ExpressJS - router module with parameters

I've been toying with NodeJS and Express for a few days, and it is pretty cool. But I've run into an issue I cannot get my head around, so I'm hoping someone else out there can help me clear this up.
I know that I can declare a module, and then pass parameters into this module via the require method.
--- App.js ----
var foo = require('./modules/Foo.js');
foo.config();
var bar= {}
require('./modules/Bar.js)(bar, foo)
--- Bar.js ---
module.exports = function(Bar, Foo) {
Bar.act = function(){
Foo.do();
}
}
I think this is a much cleaner design than having to require Foo in every module that would require using it. I also don't have to do initialization in each module that requires it.
But then comes the Router, and I can't really understand how it works. Most examples out there requires the router in each module, something like this:
--- App.js ----
var index = require('./views/index.js');
app.use('/', index);
--- Index.js ---
var express = require('express');
var router = express.Router();
var foo = require('../modules/Foo.js);
foo.config();
router.get('/', function (req, res) {
foo.do();
res.render('index');
})
module.exports = router
But then, I need to require all modules used in index.js manually. What I would really want to do is something like this:
--- App.js ----
var foo = require('../modules/Foo.js);
foo.config();
var index = require('./views/index.js')(foo);
app.use('/', index);
--- Index.js ---
var express = require('express');
var router = express.Router();
module.exports = function(foo){
router.get('/', function (req, res) {
foo.do();
res.render('index');
})
}
But writing it this way, the compiler tells me "Router.use() requires middleware, got a undefined". I can sorta see where this error comes from, (the module.exports does not return an object) but so how do I structure my code so that I can pass parameters to a module that in the end will export a Router middleware? I want to require and initialize Foo in one place, then pass it to all router modules that uses it. Is it possible somehow?
You almost got it, you just need to return the Router.
A fixed index.js could look like this:
var express = require('express');
module.exports = function(foo){
var router = express.Router();
router.get('/', function (req, res) {
foo.do();
res.render('index');
});
return router;
}
Notice the additional ; and the return.
I've also moved the instantiation of the router to the function. In node modules are cached, you can require the same module multiple times and they will all share their global variables. This can lead to unexpected results. In your case you'll overwrite the router.get handler every time and the same instance of Foo would be used for every request.

What is difference between require(path) and require(path)() in node.js

In node.js projects I have seen require(path) as well as require(path)() what does extra paranthasis refers.
When should I use require(path) and require(path)()
The require() statement returns the module.exports property from within the module that is being loaded. What you do with that depends entirely on what the module set it to.
If the module set it to a function of some kind (often called a module constructor function), then it is natural to call it with var something = require('xxx')(...);
But, if the module just exports an object with properties on it, then it would actually be a programming error to try to call it.
So, it depends entirely upon what the module you are loading is exporting.
For example, when loading the file system module, it would just be:
var fs = require('fs');
The variable fs in this case is just an object (not a function) so you would not call it - you would just reference properties on it:
fs.rename(...)
Here's an example of a module exporting a constructor function that you would call with () after it:
// myRoutes.js
module.exports = function(app) {
app.get("/", function() {...});
app.get("/login", function() {...});
}
// app.js
// other code that sets up the app object
// ....
// load a set of routes and pass the app object to the constructor
require('./myRoutes')(app);
And, here's an example of a module just exporting properties so you would not call the module itself:
// myRoutes.js
module.exports.init = function(app) {
app.get("/", function() {...});
app.get("/login", function() {...});
}
// export commonly used helper function
module.exports.checkPath = function(path) {
// ....
}
// app.js
// other code that sets up the app object
// ....
// load a set of routes and then initialize the routes
var routeStuff = require('./myRoutes');
routeStuff.init(app);
if (routeStuff.checkPath(somePath)) {
// ...
}

How can I configure koa-router to run common code before any of a certain group of routes?

I'd like to add some functionality to /module that gets executed for any matching route under that directory.
So for a given set of routes:
/module/
/module/page
/module/things
/module/things/:thingid
I want code in a router for /module to run for all of the above routes. /module doesn't render, it just fetches some common data and configures the view context. Then one of the other routes runs and renders the page.
Is this possible with koa-router? Or is there a better package?
Edit:
I think maybe I have to do a nested router and add middleware prior to the nesting like so:
var subRouter = new Router();
subRouter.get('/', function *(next){ doSomething(); });
subRouter.get('/page', function *(next){ doSomething(); });
subRouter.get('/things', function *(next){ doSomething(); });
subRouter.get('/things/thingid', function *(next){ doSomething(); });
mainRouter.use('/module',
function *(next) { doPreRouteSteps(); yield next; },
subRouter.routes()
);
Seems to be working, but I'm not sure if this is an ugly hack or what. If there is a better way, please advise.
You might consider using koa-mount to create a separate app, and then mount it under /module. The sub-app can have any pre- or post- middleware you'd like.
var mount = require('koa-mount');
var koa = require('koa');
var koaRouter = require('koa-router');
var subApp = koa();
var router = koaRouter();
router.get('/page', function *(next){ ... });
subApp.use(function*() { ...pre-route stuff... });
subApp.use(router.routes());
var mainApp = koa();
mainApp.use(mount('/module', subApp));
I like this approach because the way it encourages modularity.
koa-router can do this, i guess better.
router.use('/module/', function *(next) {
// code here
next();
});
router.get('/module/page', function *() {
this.body = 'your view';
});
on this sample, everytime the router encounters '/module'. even if there are trailing or additional params on the url. it will run the first function then proceed to any meet condition.
This is Rei Dien's response updated to 2021. Also you can pass an array of routes or "/" which will call your router.use() before any route. Example with array of routes:
router.use(["/user", "/posts"], async (ctx, next) => {
// Your code before routes...
await next();
});
router.get("/user/likes", async ctx => {
ctx.body = "Your rute code...";
});

Calling already defined routes in other routes in Express NodeJS

I am writing a web app in node.js using Express. I have defined a route as follows:
app.get("/firstService/:query", function(req,res){
//trivial example
var html = "<html><body></body></html>";
res.end(html)
});
How do I reuse that route from within express?
app.get("/secondService/:query", function(req,res){
var data = app.call("/firstService/"+query);
//do something with the data
res.end(data);
});
I couldn't find anything in the API documentation and would rather not use another library like "request" because that seems kludgey. I am trying to keep my app as modular as possible. Thoughts?
Thanks
Similar to what Gates said, but I would keep the function(req, res){} in your routes file. So I would do something like this instead:
routes.js
var myModule = require('myModule');
app.get("/firstService/:query", function(req,res){
var html = myModule.firstService(req.params.query);
res.end(html)
});
app.get("/secondService/:query", function(req,res){
var data = myModule.secondService(req.params.query);
res.end(data);
});
And then in your module have your logic split up like so:
myModule.js
var MyModule = function() {
var firstService= function(queryParam) {
var html = "<html><body></body></html>";
return html;
}
var secondService= function(queryParam) {
var data = firstService(queryParam);
// do something with the data
return data;
}
return {
firstService: firstService
,secondService: secondService
}
}();
module.exports = MyModule;
Can you simply break this out into another function, put it in a shared spot and go from there?
var queryHandler = require('special_query_handler');
// contains a method called firstService(req, res);
app.get('/firstService/:query', queryHandler.firstService);
// second app
app.get('/secondService/:query', queryHandler.secondService);
Honestly, this whole business of nesting the call back inside of the app.get(...) is not really a great practice. You end up with a giant file containing all of the core code.
What you really want is a file filled with app.get() and app.post() statements with all of the callback handlers living in different, better organized files.
If you have a lot of middleware on your route, you can benefit from spreading:
const router = express.Router();
const myMiddleware = [
authenticationMiddleware(),
validityCheckMiddleware(),
myActualRequestHandler
];
router.get( "/foo", ...myMiddleware );
router.get( "/v1/foo", ...myMiddleware );
You can use run-middleware module exactly for that
app.runMiddleware('/firstService/query',function(responseCode,body,headers){
// Your code here
})
More info:
Module page in Github & NPM;
Examples of use run-middleware module
Disclosure: I am the maintainer & first developer of this module.
I have used following way:
at userpage.js
router.createSitemap = function(req, res, callback) { code here callback(value); }
at product.js
var userPageRouter = require('userpages');
userPageRouter.createSitemap(req, res, function () {
//console.log('sitemap');
});
Also can use in same userpage.js router I can use for other routing as well. eg.
router.get('/sitemap', function (req, res, next) {
router.createSitemap(req, res, function () {
res.redirect('/sitemap.xml');
}); });
Hope this will help.

Global Variable in app.js accessible in routes?

How do i set a variable in app.js and have it be available in all the routes, atleast in the index.js file located in routes. using the express framework and node.js
It is actually very easy to do this using the "set" and "get" methods available on an express object.
Example as follows, say you have a variable called config with your configuration related stuff that you want to be available in other places:
In app.js:
var config = require('./config');
app.configure(function() {
...
app.set('config', config);
...
}
In routes/index.js
exports.index = function(req, res){
var config = req.app.get('config');
// config is now available
...
}
A neat way to do this is to use app.locals provided by Express itself.
Here is the documentation.
// In app.js:
app.locals.variable_you_need = 42;
// In index.js
exports.route = function(req, res){
var variable_i_needed = req.app.locals.variable_you_need;
}
To make a global variable, just declare it without the var keyword. (Generally speaking this isn't best practice, but in some cases it can be useful - just be careful as it will make the variable available everywhere.)
Here's an example from visionmedia/screenshot-app
file app.js:
/**
* Module dependencies.
*/
var express = require('express')
, stylus = require('stylus')
, redis = require('redis')
, http = require('http');
app = express();
//... require() route files
file routes/main.js
//we can now access 'app' without redeclaring it or passing it in...
/*
* GET home page.
*/
app.get('/', function(req, res, next){
res.render('index');
});
//...
To declare a global variable you need do use global object. Like global.yourVariableName. But it is not a true way. To share variables between modules try to use injection style like
someModule.js:
module.exports = function(injectedVariable) {
return {
somePublicMethod: function() {
},
anotherPublicMethod: function() {
},
};
};
app.js
var someModule = require('./someModule')(someSharedVariable);
Or you may use surrogate object to do that. Like hub.
someModule.js:
var hub = require('hub');
module.somePublicMethod = function() {
// We can use hub.db here
};
module.anotherPublicMethod = function() {
};
app.js
var hub = require('hub');
hub.db = dbConnection;
var someModule = require('./someModule');
the easiest way is to declare a global variable in your app.js, early on:
global.mySpecialVariable = "something"
then in any routes you can get it:
console.log(mySpecialVariable)
This was a helpful question, but could be more so by giving actual code examples. Even the linked article does not actually show an implementation. I, therefore, humbly submit:
In your app.js file, the top of the file:
var express = require('express')
, http = require('http')
, path = require('path');
app = express(); //IMPORTANT! define the global app variable prior to requiring routes!
var routes = require('./routes');
app.js will not have any reference to app.get() method. Leave these to be defined in the individual routes files.
routes/index.js:
require('./main');
require('./users');
and finally, an actual routes file, routes/main.js:
function index (request, response) {
response.render('index', { title: 'Express' });
}
app.get('/',index); // <-- define the routes here now, thanks to the global app variable
Here are explain well, in short:
http://www.hacksparrow.com/global-variables-in-node-js.html
So you are working with a set of Node modules, maybe a framework like Express.js, and suddenly feel the need to make some variables global. How do you make variables global in Node.js?
The most common advice to this one is to either "declare the variable without the var keyword" or "add the variable to the global object" or "add the variable to the GLOBAL object". Which one do you use?
First off, let's analyze the global object. Open a terminal, start a Node REPL (prompt).
> global.name
undefined
> global.name = 'El Capitan'
> global.name
'El Capitan'
> GLOBAL.name
'El Capitan'
> delete global.name
true
> GLOBAL.name
undefined
> name = 'El Capitan'
'El Capitan'
> global.name
'El Capitan'
> GLOBAL.name
'El Capitan'
> var name = 'Sparrow'
undefined
> global.name
'Sparrow'
My preferred way is to use circular dependencies*, which node supports
in app.js define var app = module.exports = express(); as your first order of business
Now any module required after the fact can var app = require('./app') to access it
app.js
var express = require('express');
var app = module.exports = express(); //now app.js can be required to bring app into any file
//some app/middleware, config, setup, etc, including app.use(app.router)
require('./routes'); //module.exports must be defined before this line
routes/index.js
var app = require('./app');
app.get('/', function(req, res, next) {
res.render('index');
});
//require in some other route files...each of which requires app independently
require('./user');
require('./blog');
this is pretty easy thing, but people's answers are confusing and complex at the same time.
let me show you how you can set global variable in your express app. So you can access it from any route as needed.
Let's say you want set a global variable from your main / route
router.get('/', (req, res, next) => {
req.app.locals.somethingNew = "Hi setting new global var";
});
So you'll get req.app from all the routes. and then you'll have to use the locals to set global data into. like above show you're all set. now
I will show you how to use that data
router.get('/register', (req, res, next) => {
console.log(req.app.locals.somethingNew);
});
Like above from register route you're accessing the data has been set earlier.
This is how you can get this thing working!
As others have already shared, app.set('config', config) is great for this. I just wanted to add something that I didn't see in existing answers that is quite important. A Node.js instance is shared across all requests, so while it may be very practical to share some config or router object globally, storing runtime data globally will be available across requests and users. Consider this very simple example:
var express = require('express');
var app = express();
app.get('/foo', function(req, res) {
app.set('message', "Welcome to foo!");
res.send(app.get('message'));
});
app.get('/bar', function(req, res) {
app.set('message', "Welcome to bar!");
// some long running async function
var foo = function() {
res.send(app.get('message'));
};
setTimeout(foo, 1000);
});
app.listen(3000);
If you visit /bar and another request hits /foo, your message will be "Welcome to foo!". This is a silly example, but it gets the point across.
There are some interesting points about this at Why do different node.js sessions share variables?.
const app = require('express')();
app.set('globalvar', "xyz");
app.get('globalvar');
I used app.all
The app.all() method is useful for mapping “global” logic for specific
path prefixes or arbitrary matches.
In my case, I'm using confit for configuration management,
app.all('*', function (req, res, next) {
confit(basedir).create(function (err, config) {
if (err) {
throw new Error('Failed to load configuration ', err);
}
app.set('config', config);
next();
});
});
In routes, you simply do req.app.get('config').get('cookie');
I solved the same problem, but I had to write more code.
I created a server.js file, that uses express to register routes.
It exposes a function,register , that can be used by other modules to register their own routes.
It also exposes a function, startServer , to start listening to a port
server.js
const express = require('express');
const app = express();
const register = (path,method,callback) => methodCalled(path, method, callback)
const methodCalled = (path, method, cb) => {
switch (method) {
case 'get':
app.get(path, (req, res) => cb(req, res))
break;
...
...
default:
console.log("there has been an error");
}
}
const startServer = (port) => app.listen(port, () => {console.log(`successfully started at ${port}`)})
module.exports = {
register,
startServer
}
In another module, use this file to create a route.
help.js
const app = require('../server');
const registerHelp = () => {
app.register('/help','get',(req, res) => {
res.send("This is the help section")
}),
app.register('/help','post',(req, res) => {
res.send("This is the help section")
})}
module.exports = {
registerHelp
}
In the main file, bootstrap both.
app.js
require('./server').startServer(7000)
require('./web/help').registerHelp()
John Gordon's answer was the first of dozens of half-explained / documented answers I tried, from many, many sites, that actually worked. Thank You Mr Gordon. Sorry I don't have the points to up-tick your answer.
I would like to add, for other newbies to node-route-file-splitting, that the use of the anonymous function for 'index' is what one will more often see, so using John's example for the main.js, the functionally-equivalent code one would normally find is:
app.get('/',(req, res) {
res.render('index', { title: 'Express' });
});

Resources