Express: accessing app.set() settings in routes - node.js

In Express, I'm led to believe that global app settings can be created by doing something similar to the following in my main app.js file:
var express = require('express'),
...
login = require('./routes/login');
var app = express();
app.configure(function(){
...
app.set('ssoHostname', 'login.hostname.com');
...
});
...
app.get('/login', login.login);
...
now in ./routes/login.js, I'd like to access app.settings.ssoHostname, but if I attempt to run anything similar to (as per: How to access variables set using app.set() in express js):
...
exports.login = function(req, res) {
var currentURL = 'http://' + req.header('host') + req.url;
if (!req.cookies.authCookie || !User.isValidKey(req.cookies.authCookie)) {
res.redirect(app.settings.ssoHostname + '/Login?returnURL=' + encodeURIComponent(currentURL));
}
};
...
it does not recognize app:
ReferenceError: app is not defined
My questions are:
Is the approach I took of using app.set() for global settings that will be re-used often the "proper" way to do it and if so...
How do I access these settings in routes?
If not using app.set() for global settings to be used often, how would I set and get custom settings in routes?

Use req.app.get('ssoHostname')

At the end of your app.js file:
module.exports = app;
And then in routes/login.js:
var app = require('../app');
Now you have access to the actual app object and won't get a ReferenceError.

Related

Keystone cant hide x-powered-by

I'm trying to remove both node.js and express x-powered-by with expressjs commands but they don't work.
Here are the commands that I'm using both where working on other projects
app.disable('x-powered-by');
or
app.set('x-powered-by', false);
Is there another way to do this in keystonejs?
Well i have found a solution to this
Instead of using it at the keystone.js you must use it on the routes - middleware
var keystone = require('keystone');
var middleware = require('./middleware');
var importRoutes = keystone.importer(__dirname);
// Common Middleware
keystone.pre('routes', middleware.initLocals);
keystone.pre('render', middleware.flashMessages);
// Import Route Controllers
var routes = {
views: importRoutes('./views'),
};
// Setup Route Bindings
exports = module.exports = function (app) {
// Views
app.set('x-powered-by', false);//<<< Place it here
app.get('/', routes.views.news);
};

how to create a nodeJS module with expressJS

I'm making a nodeJS module, and I want to use expressJS as a framework for it.
I'm trying to see, how I could go by, including a function inside and app.get(); and call it via another file, such as the actual app.
var express = require("express");
var app = express();
app.get("/", function (req, res) {
exports.type = function (text) {
console.log(req.ip);
console.log(text);
}
});
now when I use this, and i call it on the actual app like:
var web = require("directory_to_file");
var express = require("express");
var app = express();
var http = require("http").Server(app);
app.get("/", function (req, res) {
web.type("Hello, world");
});
http.listen(10022, function () {
console.log("server is up");
});
I get an error:
TypeError: Property 'type' of object #<Object> is not a function
anyone know a way to make it so I can call the function?
There are generally two things you want to export as a module - an API and a Middleware. The classic example of middleware is an authentication module. To do the middleware, just export the middleware. I tend to do a little more than that so I can configure the middleware later. Something along the lines of this:
module.exports = exports = function(config) {
// Do something with config here
return function(req, res, next) {
// your middleware here
};
};
You can then use your middleware in your main program like this:
var app = require('express')(),
mymodule = require('./mymodule');
var config = {}; // replace with whatever config you need
app.use(mymodule(config));
app.listen(process.env.PORT || 3000);
To implement an API, you will create a Router object, then attach your routes to the Router object. You can then "mount" your router in your main program. For example, you could have a file called 'myroutes.js' with the following contents:
var express = require('express'),
myroutes = express.Router();
myroutes.get('/foo', (req, res) => {
res.status(200).type('application/json').send({ myparam: 'foo' });
});
module.exports = exports = myroutes;
Have the following in your main program:
var app = require('express')(),
myroutes = require('./myroutes');
app.use('/api', require('./myroutes'));
app.listen(process.env.PORT || 3000);
Here, in 'myroutes.js', I'm defining a sub-route of /foo and then in the main program, I'm mounting that on /api - so I would access /api/foo to access that API.
In your directory_to_file you are only exporting on app.get('/') which will never be called.
You could add in your directory_to_file the following code
var express = require('express');
var router = express.Router();
router.get('/', function(req, server) {
console.log(req.ip);
});
module.exports = router;
And in your main file you could use app.use('/', web)
A short explanation:
You are creating a new express app / config in your directory_to_file file which won't be launched or used. So your app.get event won't be fired once.
That's why web.type is not a function. You are not exporting anything.
Use the way I provided. This is a commonly used method.
You could call the code I provided a "route". Create multiple routes / route files and include them in your main method.
Your code just looks confused. If I understand you correctly, what you are really trying to do (at least in Node/express terminology) is write your own middleware.
Express is designed with this in mind and it's pretty straightforward e.g.
ipLogger.js
module.exports = function(req, res, next) {
console.log(req.ip);
next();
}
app.js
var http = require("http")
, express = require("express");
, app = express()
, server = http.Server(app)
, ipLogger = require("./ipLogger.js");
app.use(ipLogger()); // log IP of all requests
// handle routes
server.listen(10022, function() {
console.log("server is up");
});

Express: passing options to an included server

I would like to develop an Express website that can run either stand-alone or as part of a larger server while allowing a degree of configuration.
For example, say I have a large main server in server.js and I write another server app.js that defines a route /* to provide a small service. I want to be able to either:
run app.js standalone, which will provide its routes through localhost:port/
define a route within server.js that maps to this server, for example so that /app/* will allow app.js to handle requests.
Reading through Smashing Node, I see that if I define an Express server and its routes in app.js, I can use: server.use('/app', require('app.js') to gain use of its routes. The problem with this approach is that I do not see how to pass any configuration options to app.js.
You could write your app.js module as a callable function:
var express = require("express");
var app; // <-- note the global
var initialize = function(conf) {
if (app) {
return app;
}
conf = conf || {};
app = express();
// here goes the configutation code, for example:
if (conf.static) {
app.use(express.static(conf.static));
}
return app;
};
if (require.main === module) {
// if standalone, fire it
initialize({ static: __dirname + "/public" });
}
// and export
module.exports = exports = initialize;
and then in other file:
var app = require("app.js")({ static: __dirname + "/public" });
Note that it is a singleton, so further calls to the module function will return the same server:
app == require("app.js")();
I'm sure you can tweak it to your needs.

Express: how to pass variables to mounted middleware

I've just started to play around with Expressjs and I'm wondering how to pass variables to mounted middleware/sub application. In the following example, I'd like the config object passed to my /blog/index
in app.js
var express = require('express');
var app = express();
//...
var config = {}
//...
app.use('/blog', require('./blog/index')
in /blog/index.js
var express = require('express');
app = module.exports = express();
app.use(express.static(...
app.get('/', function(req, res, next) {
//handle the req and res
}
Thanks,
I see two options here:
Since your blog app is an express application, you can use app.set and app.get. E.g.
blog = require('./blog/index');
blog.set('var1', value1);
blog.set('var2', value2);
...
app.use('/blog', blog);
And in blog/index.js use app.get('var1') to get the value of var1.
You can wrap the blog express application in another function that accepts configuration parameters (much like the static middleware accepts a directory name) and returns the configured application. Let me know if you want an example.
EDIT: Example for the 2nd option
app.js would look like this:
var blog = require('./blog/index');
...
var config = {};
app.use('/blog', blog(config));
and /blog/index.js like that:
var express = require('express')
module.exports = function(config) {
var app = express();
// configure the app and do some other stuffs here
// ...
return app;
}

NodeJS - accessing variables in different modules

I'm writing a mudule express-based NodeJS app. Here are important parts of my app.js:
var express = require('express')
, routes = require('./routes')
, passport = require('passport')
, LocalStrategy = require('passport-local').Strategy;
var app = module.exports = express.createServer();
var ab = 'this is a test!';
// Configuration
app.configure(function(){
...
// Routes
app.get('/', routes.index);
app.listen(3000);
Routes.index - is a controller, that executes when '/' is requested. Here is the code:
exports.index = function(req, res){
passport.serializeUser(function(user, done) {
done(null, user.id);
});
...
res.render('index.ejs', {
title: ab
})
};
Techically, index.js - is separate file, located in '/routes' folder. So, when I launch my app, it crashed cause can't find passport var, declared in main app. Also, ab also can't be found, however it was declared. If I re-declate vars in index.js, JS will create new objects for me. How can I use my vars in every module of my app? I looked through a few topics on SO, however couldn't understand – is it a common problem or just a structure of my app is wrong? Thanks!
As you have discovered, variables declared in one module don't magically appear in other modules. When it comes to modules such as passport, usually people just require them again where they're needed, so:
app.js:
var passport = require('passport'),
index = require('./routes/index');
index.js:
var passport = require('passport');
Sometimes you want to pass parameters though -- I often do it for unit testing, if I can pass in dependencies I can also mock those dependencies. Or you have an app-wide configuration you want to pass around. I usually do this:
app.js:
var ab = "foo",
index = require('/routes/index')(ab);
index.js:
module.exports = function(ab) {
// Here I have access to ab and can to what I need to do
return {
index: function(req, res) { res.send(ab) }
}
}
Other people prefer a "singleton" pattern, where each time you require a module, you check if it's already been initialized and if so, pass that instance.

Resources