Module route separation - node.js

When I use http://tes.com/routes, it will route to the api=>get('/'), instead of web=>get('/'). Why?
app.js:
var api = require('./app/routes/routes').api;
var transaction_web = require('./app/routes/routes').web;
app.use('/api/routes', transaction_api);
app.use('/routes', transaction_web);
routes.js:
var api = (function () {
router.get('/', function (req, res, next) {
...
});
return router;
})();
var web = (function () {
router.get('/', function (req, res, next) {
...
});
return router;
})();
module.exports = {
api: api,
web: web
};

The reason is because that's the order in which you're adding the routes.
This:
var api = (function () {
router.get('/', function (req, res, next) {
...
});
return router;
})();
is the same as:
router.get('/', function (req, res, next) {
...
});
var api = router;
The same thing happens with the other block where you assign web, so you end up with:
router.get('/', function (req, res, next) {
// api route
});
var api = router;
router.get('/', function (req, res, next) {
// web route
});
var web = router;
The solution would be to create separate Router instances. For example:
var api = new express.Router();
api.get('/', function (req, res, next) {
// web route
});
var web = new express.Router();
web.get('/', function (req, res, next) {
// web route
});

Related

NodeJS: route parameter at the first slash works but the same one at the second does not

The file myProject\app.js code is:
app.use('/student', require('./routes/studentsRoutes'));
app.get('/loadexercise', function (req, res) {
let result = {unit: req.query.unit, part: req.query.part};
res.json(result);
});
The file myProject\routes\studentsRoutes.js contains:
var express = require('express');
var router = express.Router();
router.get('/loadexercise', function (req, res) {
let result = {unit: req.query.unit, part: req.query.part};
res.json(result);
});
module.exports = router;
When I run the link http://localhost:55555/loadexercise?unit=1&part=1 from a browser, the render is OK like this: {"unit":"1","part":"1"}.
But when I run the link http://localhost:55555/student/loadexercise?unit=1&part=1, it shows [].
What am I doing wrong?
The request http://localhost:55555/student/loadexercise?unit=1&part=1 will fall into the route /:unit because it has a parameter and this route goes above the route /loadexercise and Express treats loadexercise as a value of the unit parameter.
You simply need to move all routes with static parts before routes with the same part of a route but as a dynamic parameter:
router.get('/loadexercise', function (req, res) {
let result = {unit: req.query.unit, part: req.query.part};
res.json(result);
});
router.get('/login', function(req, res, next) {});
router.post('/login', function(req, res, next) {});
router.get('/changepass', function(req, res, next) {});
router.post('/changepass', function(req, res, next) {});
router.get('/:unit', function (req, res) {
...

A lot of "express routers" in a single Bookshelf transaction

Bookshelf transaction is working only in callback function. How i can do it?
var express = require('express');
var router = express.Router();
router.post('/', (req, res, next) => {
Bookshelf.transaction((trx) => {
req.trx = trx;
next();
});
});
router.post('/', (req, res, next) => {
// use req.trx
});
router.post('/', (req, res, next) => {
// use req.trx
});
router.post('/', (req, res, next) => {
req.trx.commit();
});

How to pass multiple parameters from controller in node.js express

I am working with Passport, and I need to pass multiple parameters through to from my controller to my router. Basically it only passes the first one.
I want to get
app.get('/auth/steam', controllers.auth.authenticate);
to result in
app.get('/auth/steam', passport.authenticate('steam'), function(req, res) { res.render('index') };);
Right now it only loads the 1st parameter.
My controller looks like this
exports.authenticate =
passport.authenticate('steam'),
function(req, res) {
res.render('index');
};
How would I do this?
EDIT: I want to only be able to call it with controllers.auth.authenticate, not in an array like: controllers.auth.authenticate[0]!
Warning NOT tested.
You can wrap all inside function
exports.authenticate = function(req, res, next) {
passport.authenticate('steam', function(err, user, info) {
if (err) { return next(err); }
if (!user) { return res.redirect('/auth/steam'); }
res.render("index");
});
}
Or you can use router and protect ALL verbs (get, post, etc)
var express = require('express');
var router = express.Router();
router.use(function (req, res, next) {
passport.authenticate('steam');
});
router.get('/', function(req, res, next) {
res.render("index");
});
module.exports = router;
And use router on the app
var ctrl = require("yourModuleName");
app.use('/auth/steam', ctrl); // app.use NOT app.get
Other alternative is to protect only the get
var express = require('express');
var router = express.Router();
router.get('/', passport.authenticate('steam'), function(req, res, next) {
res.render("index");
});
module.exports = router;
var ctrl = require("yourModuleName");
app.use('/auth/steam', ctrl); // app.use NOT app.get
See Express routing page

Seperate api and web in route

Trying to separate api and web route:
route/index.js
var api = function () {
router.get('/:id', function (req, res, next) {
...
});
return router;
}
var web = function () {
router.get('/:id', function (req, res, next) {
...
});
return router;
}
module.exports = {
api: api,
web: web
};
app.js
var indexAPI = require('./app/routes/accounts').api;
var indexWeb = require('./app/routes/accounts').web;
app.use('/api/index', indexAPI);
but it didn't route successfully.
I have change it to and it is working:
var api = (function () {
router.get('/:id', function (req, res, next) {
...
});
return router;
})();
var web = (function () {
router.get('/:id', function (req, res, next) {
...
});
return router;
})();
module.exports = {
api: api,
web: web
};

Param parsing twice for nested routes in Express

When I make GET http://localhost:8080/messages/3/sentiments for the code below why param method is called two times? So If I have 10 routes it will be called 10 times?
var comments = new Router();
comments.get('/comments', function (req, res, next) {
res.send('Comments by message_id=' + req.message._id);
})
var sentiments = new Router();
sentiments.get('/sentiments', function (req, res, next) {
res.send('Comments by message_id=' + req.message._id);
})
var messages = new Router();
messages.param('_message', function (req, res, next, _id) {
console.log("Set message");
fs.readFile(__filename, function () {
req.message = { _id: _id };
next();
});
})
messages.use('/messages/:_message/', comments);
messages.use('/messages/:_message/', sentiments);
app.use(messages);
app.listen(8080);
Confirmed to be a bug in Express < 4.3
https://github.com/visionmedia/express/issues/2121

Resources