Unable to Split Routes into Separate Files in Express 4.0 - javascript

I'm trying to redirect all my routes ending with /api to a manager.js which will then route it to /me.
So, a fully qualified request to /me should look like /api/me. Splitting routes up into separate files was easy in Express 3.x, but I'm having trouble in 4.0.
app.js
app.use('/api',require('./routes/manager'));
manager.js
var express = require('express');
var manager = express.Router();
module.exports = function() {
manager.use('/me',require('../routes/me'));
};
me.js
var express = require('express');
var me = express.Router();
module.exports = function() {
me.route('/')
.get(function(req,res){
res.send("Welcome to Me");
});
};
When I go to localhost:8080/api/me, nothing happens, the page keeps loading.
Thanks for any help!

You are not quite properly passing through the Router objects. Keep in mind that this is what you are trying to do:
app.use('/api', express.Router());
but what you are effectively doing right now is this:
app.use('/api', function(){
express.Router()
});
So you instead of exporting a function, you should be exporting the Router itself.
manager.js
var express = require('express');
var manager = express.Router();
manager.use('/me',require('../routes/me'));
module.exports = manager;
me.js
var express = require('express');
var me = express.Router();
me.route('/').get(function(req,res){
res.send("Welcome to Me");
});
module.exports = me;

Related

nodejs module - express module.export - how to pass variable to other file?

Question is how to pass variable to other js file in the simplest way (without any routes just with module.exports).
My file structure looks like this (very simple popular structure):
ROUTES (folder)
--form.js
--test.js
VIEWS (folder)
--form.ejs
--test.ejs
index.js
package.json
index.js file (standard express app file):
var express = require('express');
var body_parser = require('body-parser');
var form = require('./routes/form.js');
var test = require('./routes/test.js');
var app = express();
app.set('view engine', 'ejs');
app.use(body_parser.urlencoded({extended:true}));
app.use('/', form);
app.use('/test', test);
var port = 3700;
var server_listen_on = app.listen(port, function()
{
console.log('Server is listening on port: ' + port);
});
form.js file:
var express = require('express');
var body_parser = require('body-parser');
var router = express.Router();
var preciousData = 'var precious_data - from form.js file';
module.exports =
{
exportsPreciousData : preciousData,
router : router
};
test.js file:
var express = require('express');
var request = require('request');
var router = express.Router();
var requireFormjs = require('./form.js');//({exportsPreciousData : exportsPreciousData});
//console.log(requireFormjs.exportsPreciousData); // I guess console.log is faster then module.exports... but
router.get('/', function(req, res, next)
{
res.render('welcome', {test : requireFormjs.exportsPreciousData});
});
// why this doesn't work - I need to use middleware function - could you provide simple working example?
//(I guessing that even if console.log print data after module.exports machinery I would still need middleware, right?)
module.exports = router;
welcome.ejs file:
<!DOCTYPE html>
<html>
<head>
<title>welcome</title>
</head>
<body>
<%= test %>
</body>
</html>
... why it's not working (without express everything runs fine)?
Simple make those other files return a function:
Test.js:
module.exports = function(preciousData) {
// do everything here
return router;
}
index.js:
var test = require('test.js')(preciousData);
Data is passed by calling the function that test.js returns and router is returned from that function

Why is my route not being hit?

Hi I have an express router that seems to not get hit when I navigate to the proper route. In my app.js:
var auth = require('./routes/auth');
app.use('/auth', auth);
In my routes/auth.js
var express = require('express');
var authRouter = express.Router();
var mongodb = require('mongodb').MongoClient;
var router = function(){
authRouter.route('/signUp')
.post(function (req, res){
console.log("Hello world");
});
return authRouter;
};
module.exports = router;
In my index.jade:
form.login-form(role='form', action='/auth/signUp', method='post', name='signUpForm' )
.form-group
label.sr-only(for='form-username') Username
input#form-username.form-username.form-control(type='text', name='userName', placeholder='Email...')
.form-group
label.sr-only(for='form-password') Password
input#form-password.form-password.form-control(type='password', name='password', placeholder='Password...')
button.btn(type='submit') Sign up!
However when I try to go to /auth/signUp all I get in terminal is: GET /auth/signUp - - ms - -
POST /auth/signUp - - ms - -
It seems to me that my auth/signUp is never hit. I was originally trying to console.log my req.body however I cannot even log a hello world.
You're wrapping your router in a function which is never called. Try just doing this instead:
var express = require('express');
var authRouter = express.Router();
var mongodb = require('mongodb').MongoClient;
authRouter.route('/signUp').post(function (req, res){
console.log("Hello world");
});
module.exports = authRouter;
first, you shouldn't really use cased urls like signUp. Try this:
var express = require('express');
var authRouter = express.Router();
var mongodb = require('mongodb').MongoClient;
var router = function(){
authRouter.post('/sign-up', function (req, res) {
console.log("Hello world");
});
return authRouter;
};
module.exports = router;
You are using wrong way of defining routers. Use this way instead.
var express = require('express');
var authRouter = express.Router();
authRouter.post('signUp', function(req, res) {
// in this code block you have to render text, html or object
res.render('index'); // or may be res.json(some_obj);
})

How to use nested middleware in express.js

I want to make a change from the actual structure of my code. This is the actual code i have:
//index.js
var routes = require('./routes');
var subdomain = require('express-subdomain');
//require express app with settings
var app = require('./app');
//export the application
module.exports = app;
// routes request like endusers-api.mydomain.ext/
app.use(subdomain('endusers-api', routes.apis.endusers));
// routes request like mydomain.ext/
app.use(routes.webapps.endusers);
//routes/index.js
var apis = {endusers: require("./apis/endusers")}
var webapps = {endusers: require("./webapps/endusers")}
var routes = {apis: apis, webapps: webapps}
module.exports = routes;
//routes/apis/endusers
var express = require('express');
var route = express.Router();
var logger = require('../../lib/logger');
route.get('/', logger("endusers-api-access"), function(req, res, next) {
res.json({
"name" : "Endusers API"
});
});
module.exports = route;
//routes/webapps/endusers.js
var express = require('express');
var route = express.Router();
var logger = require('../../lib/logger');
route.get('/', logger("endusers-webapp-access"), function(req, res, next) {
res.render('endusers/index', {title: 'Homepage'});
});
module.exports = route;
Now I want to change the above code to this (feel free to tell me if this is a good approach of doing things in Node.js or not):
//index.js
var middlewares = require('./middlewares');
var app = require('./app');
module.exports = app;
//i want to change to this
app.use(middlewares.endusersApi);
app.use(middlewares.endusersWebapp);
//Stuff for creating server and listening...
//middlewares/index.js
var middlewares = {
endusersApi : require("./apis/endusers"),
endusersWebapp : require("./webapps/endusers")
}
module.exports = middlewares;
//middlewares/apis/endusers.js
//TODO
//middlewares/webapps/endusers
//TODO
How should I write the TODO portions above. It look like we will need nested middlewares (a middleware calling another middleware). Please, your suggestions.
I found the answer using by express.Router().all() method.
//middlewares/apis/endusers.js
var routes = require('../../routes');
var express = require('express');
var middleware = express.Router();
middleware.all('/',subdomain('endusers-api', routes.apis.endusers));
//the two next lines are alternatives to the line above
//middleware = subdomain('endusers-api', routes.apis.endusers); //can assign only one route
//middleware.use(subdomain('endusers-api', routes.apis.endusers)); // can use many routes
module.exports = middleware;
//middlewares/webapps/endusers.js
var routes = require('../../routes');
var express = require('express');
var middleware = express.Router();
middleware.all('/', routes.webapps.endusers);
//the two next lines are alternatives to the line above
//middleware = routes.webapps.endusers; //can assign only one route
//middleware.use(routes.webapps.endusers); // can use many routes
module.exports = middleware;

Cannot Load Routes in ./src/routes/index.js from ./app.js

very new to nodejs here. I've tried to put routes in app.js without problem. However, after moving all the routes to a separate file under PROJECT_DIR/src/routes/index.js, and then I open the page in browser it says "Cannot GET /wines". Here's code in app.js and src/routes/index.js:
// app.js
var express = require('express');
var app = express();
var path = require('path');
global.app = express();
require('./src/routes/index');
// also tried: require(path.join(__dirname, './src/routes/index'));
global.server = app.listen(3000, '0.0.0.0', function () {
var host = server.address().address;
var port = server.address().port;
console.log('Example app listening at http://%s:%s', host, port);
});
// ./src/routes/index.js
// tried console.error(app); and it printed all the stuff about app in the server log
app.get('/wines', function(req, res) {
res.send([{name:'w1'}, {name:'w2'}]);
});
app.get('/', function (req, res) {
res.send('Hello World!');
});
I'm sure I'm missing something. Any help is appreciated!
Problem
Honestly, I am not sure why what you are doing does not work.
The file can be found because otherwise, Node would throw an error, and the fact that you can access app from the routes file means app is accessible.
I have a suspicion that this may be due to garbage collection -- because you do not hold a reference to the module, it may be preemptively destroyed.
What's more, there is a construct in Express called a router that probably exists for this exact purpose.
Solution
While I'm not sure about the problem I am sure about the solution -- use a router, like this:
var express = require('express');
var router = express.Router();
router.get('/wines', function(req, res) {
res.send([{name:'w1'}, {name:'w2'}]);
});
router.get('/', function (req, res) {
res.send('Hello World!');
});
module.exports = router;
And then in your app.js file, do this:
var routes = require('./routes/index');
app.use('/', routes);
Another benefit of routers is that you do not have to pollute the global object anymore..
You need to use export in index.js
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
and use it like this in app.js
var router = require('./src/routes/index');

Cannot figure out how to render a new page in express

I have this ships.js in my routes folder:
var express = require('express');
var router = express.Router();
/* GET Ships page. */
router.get('/ships', function(req, res, next) {
res.render('ships', { title: 'Express' });
});
module.exports = router;
And I have these to statements in my app.js:
var routes = require('./routes/index');
var users = require('./routes/users');
var ships = require('./routes/users');
and
app.use('/', routes);
app.use('/ships', ships);
app.use('/users', users);
However if I navigate to localhost:3000/ships I receive the following message:
respond with a resource
Sorry have read the docs, just not to snazzy with express.
You have two errors in you app module:
1.Invalid require call for ships route:
var ships = require('./routes/users'); <--
// should be:
var ships = require('./routes/ships');
2.Invalid router using in app.use:
app.use('/ships', ships);
// should be:
app.use(ships); // and the same for others

Categories