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 fra
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');
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;
}
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?.
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');
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' });
});