What is difference between require(path) and require(path)() in node.js - 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)) {
// ...
}

Related

Express: how can I get the app from the router?

I know I can get the Express app from inside an individual route with:
req.app
However I need to start a single instance of a module inside routes/index.js, i.e.:
var myModule = require('my-module')(propertyOfApp)
How can I get the express app from the router?
It really depends on your own implementation, but what I suggested in the comments should be working:
// index.js
module.exports = function(app) {
// can use app here
// somehow create your router and do the magic, configure it as you wish
router.get('/path', function (req, res, next) {});
return router;
}
// app.js
// actually call the function that is returned by require,
// and when executed, the function will return your configured router
app.use(require('./index')(app));
p.s.
Of course this is just a sample - you can configure your router with path, and all kind of properties you wish. Cheers! :)

What does double parentheses mean in a require

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));
...

nodejs access main script context

Diving into node, I have a question on how an included script, can access the main's script methods or variables
For instance, say that I have a logger object initiated in the main script and I include another js file, which needs access to the logger. How can I do that, without injecting the logger to the included script.
//main node script
var logger = require('logger'),
app = require("./app.js")
//app.js
function something(){
//access logger here !!!!!!!
}
exports.something = something
Hope it is clear
Thanks
Try doing:
//main node script
var logger = require('logger'),
app = require("./app.js")(logger);
//app.js
var something = function (logger){
logger.log('Im here!');
}
module.exports = exports = something;
Edit:
If you want to split your main app's code into different files, on your main script file you can do something like: (This is how I'm splitting my main app.js into different sections)
// main app.js
express = require('express');
...
/* Routes ---------------------*/
require('./config/routes')(app);
/* Socket IO init -------------*/
require('./app/controllers/socket.io')(io);
/* Your other file ------------*/
require('./path/to/file')(app);
...
// config/routes.js
module.exports = function(app){
app.configure(function(){
app.get('/', ...);
...
}
}
// app/controllers/socket.io.js
module.exports = function(io){
// My custom socket IO implementation here
}
// ...etc
Edit 2:
Your function can also return a JS object, in case you want to do something on the main app.js with a custom script.
Example:
// main app.js
...
/* Some controller ---------------------*/
var myThing = require('./some/controller')(app);
myThing.myFunction2('lorem'); // will print 'lorem' on console
...
// some/controller.js
// Your function can also return a JS object, in case you want to do something on the main app.js with this require
var helperModule = require('helperModule');
module.exports = function(app){
var myFunction = function(){ console.log('lorem'); }
// An example to export a different function based on something
if (app.something == helperModule.something){
myFunction = function() { console.log('dolor'); }
}
return {
myFunction: myFunction,
myFunction2: function(something){
console.log(something);
}
}
}
You can also simply export a function or an object containing functions, without sending any parameter like this:
// main app.js
...
var myModule = require('./path/to/module');
myModule.myFunction('lorem'); // will print "lorem" in console
...
// path/to/module.js
module.exports = {
myFunction: function(message){ console.log(message); },
myFunction2: ...
}
Basically, whatever you put inside module.exports is what gets returned after the require() function.
module.exports is what is returned when you require the file. in #DavidOliveros example, that's a function that takes app or io as parameters. the function is executed right after the require takes place.
If you want to expose a method of the included script to the main, try this:
// child.js
module.exports = function(app){
var child = {};
child.crazyFunction = function(callback){
app.explode(function(){
callback();
});
};
child.otherFunction = function(){};
return child;
};
// app.js
var express = require('express');
var app = module.exports = express();
var child = require('./child.js')(app);
app.get('/', function(req, res){
child.crazyFunction(function(){
res.send(500);
});
});

How to access this.property of class in prototype method in nodejs

Here is what i am trying to do. I am writing an app in nodejs express and trying to divide different parts of apps in separate modules. I have some problem access this variable in middleware functions
Below is my routes module
"use strict";
function route(params){
var app = params.app;
var ApiHelper = require('../library/apiHelper').init(params);
//get
app.get('/', Api.index);
app.get('/check', ApiHelper.validateRequest, Api.check);
}
module.exports = route;
My ApiHelper class
"use strict";
function ApiHelper(params){
this.params = params;
}
module.exports.init = function (params){
return new ApiHelper(params);
};
ApiHelper.prototype.validateRequest = function validateRequest(req, res, next){
console.log(this.params);//this is undefined
};
I am unable to access this.params in validateRequest object of the ApiHelper
You're losing the binding by passing only the validateRequest method. You can rebind it like this:
app.get('/check', ApiHelper.validateRequest.bind(ApiHelper), Api.check);

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.

Resources