I'm using express in my app.js I set something like this
var express = require('express');
var app = express();
app.set('myVar', 'hello');
then in my controller I want to get the value. I do
var express = require('express');
var app = express();
console.log(app.get('myVar')) // undefineded
Any idea why?
Your controller creates a new, fresh instance of Express. If you want to be able to share variables, you need to pass the instance from app.js to your controller:
// app.js
var express = require('express');
var app = express();
app.set('myVar', 'hello');
require('./controller')(app);
// controller.js
module.exports = function(app) {
console.log(app.get('myVar'));
};
EDIT: judging by the comments, the issue isn't so much passing app around, but moving parts of the application to separate modules. A common setup to enable that would look like this:
// app.js
var express = require('express');
var app = express();
app.set('myVar', 'hello');
app.use('/api', require('./controller/auth'));
// controller/auth.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
console.log(req.app.get('myVar'));
return res.send('hello world');
});
module.exports = router;
In your example you are instantiating a second app that you then try to get the value from. You need to get from the exact same object:
var express = require('express');
var app = express();
app.set('foo', 'bar');
app.get('foo');
If you are new to express, you can use the cli generator to scaffold out an application that shows you a sane pattern how to use the same express instance throughout your whole application.
Related
Is express() function used in the second statement a global function?.
Where can I find its declaration?. I could not find it in my project folder.
var express = require('express');
var app = express();
var fs = require("fs");
Here is what you are doing:
// creating a variable named express and storing return value of require function
// require is a nodejs function, in this case it is called with parameter called express which loads express module
var express = require('express');
// Executing the function stored in express variable
// And storing the result into app variable
var app = express();
So, where does the express comes, you are declaring it in line 1. var express = require('express') is just a convention, you can use any valid variable name. Following would also work:
var expServer = require('express');
var app = expServer();
Express is a npm module and you need to import it in order to use it, jsut like other npm packages.
Where can I find its declaration?. I could not find it in my project folder.
Its declaration is in the node_modules directory and you don't have to do anything with it.
Here is the example for using express and creating a server from it.
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send("Hello world!");
});
app.listen(3000);
I had all my routes in server.js but I wanted to make it modular and put into a folder called routes. I created a file called apis.js in routes folder but as I did that I get TypeError: app.post is not a function
server.js:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencode = bodyParser.urlencoded({ extended: true});
app.use(express.static('public'));
var apis = require('./routes/apis');
app.use('/', apis);
module.exports = app;
apis.js:
module.exports = function(app){
app.get('/', function(req, res) {
res.send('OK');
});
app.post('/idea', function(req, res) {
...
});
};
Also, having module.exports = app in server.js is important as I have tests running and I want a instance of app everytime.
What am I missing?
Better approach :-
server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencode = bodyParser.urlencoded({ extended: true});
app.use(express.static('public'));
var apis = require('./routes/apis');
app.use('/', apis);
module.exports = app;
apis.js :-
var router = require('express').Router();
router.post('/url',function(req,res,next){
//your code
})
module.exports = router
You need to pass in your express app into your apis module so it can attach the routes to your app. If you want to use app.use to put your routes in a different root path, you can create another express router, and attach your routes to that, then app.use that router:
server.js:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var urlencode = bodyParser.urlencoded({ extended: true});
app.use(express.static('public'));
var apis = express.Router();
require('./routes/apis')(apis);
app.use('/', apis);
module.exports = app;
There's a couple different methods for connecting your app to your routes, and it looks to me like you are mixing them together, resulting in your error.
The fix already mentioned...
var router = require('express').Router();
router.post('/url',function(req,res,next){
//your code
})
module.exports = router
...works with the way you currently have your server.js file set up.
Another method that doesn't require you to modify your apis.js file is to require it in server.js using
require("./routes/apis.js")(app);
instead of
var apis = require('./routes/apis');
app.use('/', apis);
This ensures that the variable app is passed into the function in apis.js
The first version is recommended, but hopefully this explains why you are getting confused between the two, i.e. because the second is an alternate version.
See Differences between express.Router and app.get? for more information on why the router version is recommended.
I'm trying to organize routes in express. But I'm having trouble getting a simple setup to work. I have two files, api.js, which has the routing info, and index.js, which runs the server.
However, when I try this, I get no response on localhost:3000.
api.js
var express = require('express');
module.exports = function() {
var router = express.Router();
router.get('/', function(req, res) {
res.send('im the home page!');
});
return router;
}
index.js
var express = require('express');
var app = express();
var router = require('./api');
app.use('/',router);
app.listen(3000);
console.log('Listening on port 3000!');
However, when I change api.js to this, it works:
api.js
var express = require('express');
var router = express.Router();
router.get('/', function(req, res) {
res.send('im the home page!');
});
module.exports = router;
I don't understand why the bottom api.js works when the top one doesn't. Shouldn't module.exports return the same express Router in both cases?
The difference is that in the first version you're exporting a function that returns the router vs the second version where you're exporting the router itself.
In the first version, Express calls your exported function, passing it req and res, expecting it to somehow handle the request. The exported function of course is not designed to handle a request (it's just creating a router and returning it), so the request times out.
I tried to separate my node routing into two parts: HTML/App and REST. Here is what I've done:
app.js:
var appPort = process.env.PORT || 80;
var express = require('express');
var http = require('http');
var appRouter = require('./routes/index');
var restRouter = require('./routes/rest');
var app = express();
var srv = http.createServer(app);
app.set('port', appPort);
app.set('view engine', 'jade');
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api/rest/', restRouter); // this seems not working .. I never get the expected response
app.use('/', appRouter); // I get this even with localhost/api/rest/...
var server = srv.listen(app.get('port'), function() {
debug('Express server listening ' + server.address().address + ':' + server.address().port);
});
index.js:
var express = require('express');
var router = express.Router();
router.get('/*', function (req, res) {
res.send('HOME')
});
module.exports = router;
rest.js
var express = require('express');
var router = express.Router();
router.get('/api/rest/*', function(req, res) {
res.send('REST API');
});
module.exports = router;
My questions:
1. It's possible in general to build multiple routers in this way?
2. Does the sequence of get.use matter, and/or do I have to deal with 'next'?
3. In case I would like to access a database inside the router can I hand over a parameter like this:
// ...
var client = new pg.Client(dbConnection);
// ...
app.use('/', appRouter(client));
1) It is possible to build multiple routers this way.
Because you are using this:
app.use('/api/rest/', restRouter);
your route calls in rest.js will be relative to /api/rest/ which means your code should be modified in rest.js to look like this:
router.get('*', function(req, res) {
res.send('REST API');
});
I would also encourage you to see the Express multi-router example on GitHub. It illustrates this point very clearly by showing a REST app with versioned routes.
2) The order of things matter
See the Express documentation for app.use and you will note:
Middleware functions are executed sequentially, therefore the order of
middleware inclusion is important.
If you reverse the order of your app.use calls, the router.get('/*', function (req, res) { line in index.js will catch everything before you get to other routes...defeating your purpose.
Also, if you don't call next, Express has no way to know that you are done or even that you want to continue to the next middleware or route.
3) The database question is a modules/scope question
This is more of a scope question than an Express question. I'd suggest looking up some of the excellent writing about javascript scope and also on how Node handles modules.
My requires:
//app.js Socket IO Test
var app = require('express').createServer(),
redis = require('socket.io/node_modules/redis'),
io = require('socket.io').listen(app);
My error:
Warning: express.createServer() is deprecated, express
applications no longer inherit from http.Server,
please use:
var express = require("express");
var app = express();
How do I modify my declarations to avoid this error? I understand this methodology is now deprecated for Express, just not sure what it needs to be changed to...
Thanks in advance!
Simply replace var app = require('express').createServer() with:
var express = require("express");
var app = express();