Can I pass data through the next function in Express? - node.js

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.

Related

How to pass one of multiple middleware nodejs

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

Koa2: how to write chain of middleware?

So in express, we can have a chain of middleware, copies an example:
middleware = function(req, res){
res.send('GET request to homepage');
});
app.get('/', middleware, function (req, res) {
res.send('GET request to homepage');
});
What's the equivalent way to write this in koa2 please ?
I'm thinking of using it for the route, for each route i want to have a middleware to check if user is already logged in.
Thanks !
If you're simply interested in making sure a middlware runs for every route, all you have to do is register the middleware before you register your routing middelware.
app.use(middleware);
As long as you call this before you 'use' your router, it will be called for every request. Just make sure you call the next function. This is how your middleware might look like:
function middleware(ctx, next) {
// Authenticate user
// Eventually call this
return next();
}

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

Node.js matching the url pattern

I need an equivalent of following express.js code in simple node.js that I can use in middleware. I need to place some checks depending on the url and want to do it in a custom middleware.
app.get "/api/users/:username", (req,res) ->
req.params.username
I have the following code so far,
app.use (req,res,next)->
if url.parse(req.url,true).pathname is '/api/users/:username' #this wont be true as in the link there will be a actual username not ":username"
#my custom check that I want to apply
A trick would be to use this:
app.all '/api/users/:username', (req, res, next) ->
// your custom code here
next();
// followed by any other routes with the same patterns
app.get '/api/users/:username', (req,res) ->
...
If you only want to match GET requests, use app.get instead of app.all.
Or, if you only want to use the middleware on certain specific routes, you can use this (in JS this time):
var mySpecialMiddleware = function(req, res, next) {
// your check
next();
};
app.get('/api/users/:username', mySpecialMiddleware, function(req, res) {
...
});
EDIT another solution:
var mySpecialRoute = new express.Route('', '/api/users/:username');
app.use(function(req, res, next) {
if (mySpecialRoute.match(req.path)) {
// request matches your special route pattern
}
next();
});
But I don't see how this beats using app.all() as 'middleware'.
You can use node-js url-pattern module.
Make pattern:
var pattern = new UrlPattern('/stack/post(/:postId)');
Match pattern against url path:
pattern.match('/stack/post/22'); //{postId:'22'}
pattern.match('/stack/post/abc'); //{postId:'abc'}
pattern.match('/stack/post'); //{}
pattern.match('/stack/stack'); //null
For more information, see: https://www.npmjs.com/package/url-pattern
Just use the request and response objects as you would in a route handler for middleware, except call next() if you actually want the request to continue in the middleware stack.
app.use(function(req, res, next) {
if (req.path === '/path') {
// pass the request to routes
return next();
}
// you can redirect the request
res.redirect('/other/page');
// or change the route handler
req.url = '/new/path';
req.originalUrl // this stays the same even if URL is changed
});

Pass req variables from .param to .use?

The code below demonstrates trying to log req.hash_id from middleware. It's showing up for me as undefined. Is there anyway that I can get this to work? Or easily parse ":hash" out in regular .use middleware?
app.param("hash",function(req, res, next, id){
req.hash_id = id;
return next();
});
app.use(function(req, res, next){
console.log(req.hash_id);
return next();
});
I don't think you can use req.params inside a middleware function as it is bound to specific routes. You could use req.query though, but then you have to write your routes differently, e.g. /user?hash=12345abc. Not sure about passing the value from app.param to app.use.
If you have a specific structure for your routes, like /user/:hash you could simply write
// that part is fine
app.param('hash',function(req, res, next, id){
req.hash_id = id;
return next();
});
app.all('/user/:hash', function(req, res, next) { // app.all instead app.use
console.log(req.hash_id);
next(); // continue to sending an answer or some html
});
// GET /user/steve -> steve

Resources