Express JS Doesen't Work - node.js

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;

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) {
...

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

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 to group api in express

Here is the example:
var app = require('express')();
function validateToken(req, res, next) {
// Do something with request here
next();
};
app.get('/user/login', function(req, res) {
//code
});
app.post('/user/register', function(req, res) {
//code
})
app.put('/user/register', validateToken, function(req, res) {
//code
})
app.delete('/user/delete', validateToken, function(req, res) {
//code
})
If I have 10 api that need validToken, I should add validToken middleware 10 times, like:
app.method('......', validateToken, function(req, res) {
//code
})
app.method('......', validateToken, function(req, res) {
//code
})
....
app.method('......', validateToken, function(req, res) {
//code
})
app.method('......', validateToken, function(req, res) {
//code
})
How can I group api by using the same middleware?
Here's how to re-use the same callback function for multiple routes (like middleware):
var app = require('express')();
function validateToken(req, res, next) {
// Do something with request here
next();
};
app.get('/user/login', function(req, res) {
// code
});
app.post('/user/register', function(req, res) {
// code
});
// Be sure to specify the 'next' object when using more than one callback function.
app.put('/user/register', validateToken, function(req, res, next) {
// code
next();
});
app.delete('/user/delete', validateToken, function(req, res, next) {
// code
next();
});
Also, you can replace app.METHOD (e.g. .post, .get, .put, etc.) with app.all and your callback will be executed for any request type.
Just wrong, so do not put into mass participation of the (Google translated from: 刚才看错了,改成这样就不用放进传参了)
var group = {url:true,url:true,url:true};
app.use(function(req,res,next){
if(group[req.url]){
// Do something with request here
next();
} else {
next();
}
})

How to use single view for several router?

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');
});

Resources