How to use single view for several router? - node.js

I have the following:
var router = express.Router();
router.get('/', function(req, res) {
res.render('layout.jade');
});
router.get('/about', function(req, res) {
res.render('layout.jade');
});
As you can see from the code above I use single layout.jade for two routes. How to combine it with single route definition to remove duplicate code? Something like the following:
router.get('/|/about', function(req, res) {
res.render('layout.jade');
});

I'd keep the routes separate. Either redirect to the other route or combine your callback.
var router = express.Router();
router.get('/', index);
router.get('/about', index);
function index(req, res) {
res.render('layout.jade');
}
If you really must do this, you can use a regex.
router.get(/\/(about)?/, function(req, res) {
res.render('layout.jade');
});

Related

I wanted to automate the model and route parts in node.js express

I wanted to automate the model and route parts in node.js express.
For example, the index.js of routes originally looked like this.
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index', {title:'Express' });
});
router.get('/a1', function(req, res, next) {
res.render('a1', {title:'Repetitive router.get' });
});
router.get('/a2', function(req, res, next) {
res.render('a2', {title:'Repetitive router.get' });
});
router.get('/a3', function(req, res, next) {
res.render('a3', {title:'Repetitive router.get' });
});
module.exports = router;
I don’t want to hard-code this every time
router.get function part
var express = require('express');
var router = express.Router();
var AAA = require('myGetAll');
AAA.add('/a1', a1, {title:'Repetitive router.get' });
AAA.add('/a2', a2, {title:'Repetitive router.get' });
AAA.add('/a3', a3, {title:'Repetitive router.get' });
/* GET home page. */
for(let i = 0; i <AAA.count(); i++){
router.get(AAA.itemPath[i], function(req, res, next) {
res.render(AAA.itemFile[i], AAA.itemParameter[i]);
});
}
module.exports = router;
I would like to do it this way.
Would it be okay to do this?
if not
MVC like express, but
Recommend a framework with better code automation.
Thank you.
There is a good way you could achieve this using route params.
router.get('/:param(a+[1-3])', function(req, res, next) {
const parameter = req.params.param;
res.render(parameter, {title:`Repetitive router.get this ${parameter}` });
});
You can pass an optional regular expression to the route to match the desired param, or just handle the input inside your code logic (in this case i´ve added a regex to match a1-a3)
https://expressjs.com/en/guide/routing.html

Express JS Doesen't Work

I have a weird problem about Express.js
I have code like this
app.get('/', function(req, res) {
res.send('Homepage');
});
app.get('/developers', function(req, res) {
res.send('Developers');
});
When i go to my localhost, i see Homepage text, when i go to /developers page, i see developers text, but when i go to /developers/developer page, i can't see the result.
app.get('/developers/developer', function(req, res) {
res.send('Developer test');
});
Why first and second routes work and why third route doesen't work?
This is because of the order of the route you have entered. app.get matches /developers first and follows the callback for it only. Try passing /developers/developer route above the /developers route. It will work.
Like this
app.get('/', function(req, res) {
res.send('Homepage');
});
app.get('/developers/developer', function(req, res) {
res.send('Developer test');
});
app.get('/developers', function(req, res) {
res.send('Developers');
});
Also, you can inline the /developers/developer within the /developers route
index.js
var developer = require('developer');
app.get('/', function(req, res) {
res.send('Homepage');
});
app.use('/developers', developer());
developer.js
var router = express.Router();
var developer = function() {
var api = router();
api.get('/', function(req, res) {
res.send('Developers');
});
api.get('/developer', function(req, res) {
res.send('Developer test');
});
};
module.exports = developer;

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

How do I POST/GET to the root of a route?

In my very simple app I have a users route which is hit when I browse to http://localhost/api/users
Is it possible for me to handle a post or get request to that url without appending anything extra to the route? Using the code below the route handler fires when I post to http://localhost/api/users/new but not to http://localhost/api/users and when I try get http://localhost/api/users/13 but not http://localhost/api/users
I know I could use router.post('/', function(req, res) {}); to post to http://localhost/api/users/ but that extra slash seems inelegant
app.js
var express = require('express');
var users = require('./routes/user');
var app = express();
app.use('/api/users', users);
module.exports = app;
routes\user.js
var express = require('express');
var User = require('../models/user');
var router = express.Router();
router.post(function(req, res) {
// post to root
});
router.post('/new', function(req, res) {
// post to /new
});
router.get(function (req, res, next) {
// get root
});
router.get('/:id', function (req, res, next) {
// get /id
});
module.exports = router;
in routes/user.js, you can simply write:
router.post('/', function (req, res, next) {
// post to /api/user or /api/user/
});
router.get('/', function (req, res, next) {
// get /api/user or /api/user/
});
This would work for both: http://localhost/api/users as well as http://localhost/api/users/
Also, there's nothing inelegant about having a / at the end of the url!
You can use an empty route like this :
router.get("", function (req, res, next) {
// get root
});
You will be able to access to /api/user as well as /api/user/
Also you can handle the route with the route method of router to simplify the code and make it more "elegant" :
router.route('/')
.get(function(req, res){}) // GET method of /api/users
.post(function(req, res){}) // POST method of /api/users
.put(function(req, res){}) // PUT method of /api/users
.delete(function(req, res){}) // DELETE method of /api/users
http://expressjs.com/es/api.html#router.route

Passing extra parameters to route handlers in Express

I'm relatively new to Express, and I'm looking for a way to make routes more reusable. In my app, I will have quite a few routes that can be passed to a generic handler, but will have different templates.
Example:
app.get('/about', function(req, res) {
res.render('about.html');
});
app.get('/', function(req, res) {
res.render('home.html');
});
While this example is contrite, I have 30+ such routes. What I would like to be able to do is something like this:
app.get('/about', generic.render('about.html'));
or otherwise somehow pass the template name to the function that returns res.render Is this possible in Express? All of my attempts to work around this result in variables being undefined.
I would prefer to not do something like this, tightly coupling my route parameters and template names:
app.get('/:template', function(req, res) {
res.render(req.params.template + '.html');
});
You could just make a a simple middleware that does this for you. Example:
function simpleRender(file, opts) {
opts || (opts = {});
return function(req, res) {
res.render(file, opts);
};
}
Then just use it like:
app.get('/about', simpleRender('about.html'));
app.get('/', simpleRender('home.html'));
This is how I do it:
const handler = (req, res, template) => {
res.render(template)
}
app.get('/about', (req, res) => {
handler(req, res, 'about.html')
})
This is a best practice for me
app.get('/:template',(req, res, next) => {
res.locals = `${template}.html`;
next();
},
renderMethod
);
function renderMethod(req, res){
res.render(res.locals)
}

Resources