How to pass one of multiple middleware nodejs - node.js

I have a router like this
router.post("/roomplayers",[authjwt.verifyTokenAdmin,authjwt.finishedRoomManagement,authjwt.activeRoomManagement],
RoomController.findPlayers)
and I would to get the controller RoomController.findPlayers if the admin have this cofinishedRoomManagementdepermission
OR this activeRoomManagement
How can I do that

If your question is how to pass through many middleware's in your route the solution is below.
const tokenMiddleWare = (req, res, next) =>{
//Your code here
next();
}
const isAdminMiddleWare = (req, res, next)=>{
//Your code here
next();
}
So now that we have two middlewares and one controller(I omitted it though) now you can work on route and pass those middlewares and controller but before I start I want point something important
So with the next you want to push the user down out of the middleware driving them closer to the route that they want to hit only when they meet all you validation that's when you want to push them down
router.post('/api/login', tokenMiddleWare, isAdminMiddleWare, (req, res)=>{
authController.login(req, res);
})
Now this would be how you pass down multiple middlewares and using your controller

Related

Can you extend controller in Nodejs/Express?

I've a route A that uses controller 1.
#A
router.get("/:id", require("./user_get"));
I want to use same logic for route B but only serve different html.
#B
router.get("/:id", ????);
I could copy paste code from user_get to new file. But I was wondering is there a way to extend it. Can I change res.render value somehow if I simply include user_get in new file.
What you want to do is separate out whatever action you're doing in userGet into a middleware.
const userGet = (req, res, next) => {
// whatever you use to get the user
// if your user getting is async the following lines would of course need to be in your `.then`
res.locals.user = user
next()
)}
Notice the middleware signature -- a function with req, res, and next, the use of res.locals, and the call to next at the end.
Then you'd write your route handlers:
const routeOneHandler = (req, res) => {
res.render('templateForRouteOne', { user: res.locals.user })
}
const routeTwoHandler = (req, res) => {
res.render('templateForRouteTwo', { user: res.locals.user })
}
and update your routes like so:
// route one
router.get('/:id', userGet, routeOneHandler)
// route two
router.get('/:id', userGet, routeTwoHandler)
If the concept of middleware and next is new to you, I recommend checking out the Express documentation, or see the info in this answer.

How to handles parameters in nested routes in express js?

I have been experimenting with nested routes as they are convenient in passing on variables
router.post('/postlinkone', function(req, res, next){
//define few variables (x,y)
//render or redirect to close this route
router.post('/postlinktwo', function(req, res, next){
//use (x,y)
//render or redirect
}
}
The problem is that express is able to pass on the variables (x,y) during initialization to postlinktwo however these variables are not refreshed in next cycles. Is there a way to hard refresh them or is there a easier way to pass variables
Express has the philosophy of building on the req object.
Instead of nesting routes, have independent routes that modify req, altering stuff that you want.
router.get('/routeOne', function(req, res, next) {
// do something
req._data = {};
req._data.x = 'bla bla';
// call next to move to the next route middleware
next();
});
router.get('/routeOne', function(req, res, next) {
// check if the params are still there.
console.log(req._data);
});

Express 4: router syntax

I am using Express 4 with the new router. At least one thing continues to confuse me, and it is a syntax problem - I am wondering if there is a regex that can do what I want. I have a standard REST api, but I want to add batch updates, so that I can send all the info to update some users models with one request, instead of one PUT request per user, for example. Anyway, I currently route all requests to the users resources, like so:
app.use('/users, userRoutes);
in userRoutes.js:
router.get('/', function (req, res, next) {
//gets all users
});
router.put('/:user_id', function (req, res, next) {
//updates a single user
});
but now I want a route that captures a batch request, something like this:
router.put('/Batch', function (req, res, next) {
//this picks up an array of users from the JSON in req.body and updates all
});
in other words, I want something which translates to:
app.use('/usersBatch, function(req,res,next){
}
...but with the new router. I can't get the syntax right.
I tried this:
app.use('/users*, userRoutes);
but that doesn't work. Does anyone know how to design this?
I'm guessing that the call to [PUT] /users/Batch is being picked up by the [PUT] /users/:user_id route. The string /:user_id is used as a regular expression causing it to also collect /Batch.
You can either move /Batch before /:user_id in the route order, refine the regex of /:user_id to not catch /Batch or change /Batch to something that won't get picked up too early.
(plus all the stuff Michael said)
REST doesn't include a POST as a list syntax. That's because each URL in REST point to an individual resource.
As an internet engineer I haven't seen any bulk PUTs or POSTs, but that said, it's your app, so you can make whatever API you like. There are definitely use cases for it.
You'll still need to describe it to Express. I would do it like this:
var express = require('express');
var router = express.Router();
router.get('/', function (req, res) {}); // gets all users
router.post('/:user_id', function (req, res) {}); // one user
router.put('/:user_id', function (req, res) {}); // one user
router.patch('/:user_id', function (req, res) {}); // one user
router.delete('/:user_id', function (req, res) {}); // one user
app.use('/user', router); // Notice the /user/:user_id is *singular*
var pluralRouter = express.Router();
pluralRouter.post('/', function (req, res) {
// req.body is an array. Process this array with a foreach
// using more or less the same code you used in router.post()
});
pluralRouter.put('/', function (req, res) {
// req.body is another array. Have items in the array include
// their unique ID's. Process this array with a foreach
// using +/- the same code in router.put()
});
app.use('/users', pluralRouter); // Notice the PUT /users/ is *plural*
There are other ways to do this. Including putting comma-delimited parameters in the URL. E.g.
GET /user/1,2,3,4
But this isn't that awesome to use, and vague in a PUT or POST. Parallel arrays are evil.
All in all, it's a niche use case, so do what works best. Remember, the server is built to serve the client. Figure out what the client needs and serve.

Routing in Express.js

I am currently express router in Node.js and having a problem like below. Let's say I have two url; one is to get a user info and one is to register users to an application.
http://example.com/users/:idUser (this will give a information of a user)
http://example.com/users/registration (this will allow a user registration)
The problem I have facing is when I call registration, the router is working with idUser; so I had to edit like user/registration instead of users. If I want to use as users/registration, which kinds of work do I have to do. I am still a newbie in Node.js.
Thanks.
You need to order the routes appropriately so that the registration route comes before.
app.get('/users/registration', function(req, res, next) {
....
});
app.get('/users/:userId', function(req, res, next) {
....
});
Just invert the order, like this:
app.get('/users/registration', function(req, res, next) {
...
});
app.get('/users/:userId', function(req, res, next) {
...
});

Can I pass data through the next function in Express?

In using Express, I have a route like:
app.get('*', function (req, res, next) {
// no route is matched
// so call next() to pass to the static middleware
next();
});
There's another route that is something like app.get('/myroute', function(req, res, next)...
Can I pass information through to that route from the first one via next?
Thanks #amakhrov. I can use res.locals and store information.

Resources