I am using express and pug, there are some values that I would like to pass to pug on every request, for example: req.session and req.path. Passing these values to the render() method every time just seems too redundant.
So instead of doing something like this:
app.get('/', (req, res) => {
res.render('home', {session: req.session})
})
app.get('/profile', (req, res) => {
res.render('profile', {session: req.session})
})
The more routes that get added, the more of those items I need to manage. Is there a global way that I can set them once other than app.locals so they are unique per request?
You can set variables that are available to every template on each request using a bit of custom middleware and locals. This same approach works for all templating systems that Express can use, not just Pug.
Put the following before your routes.
app.use((req, res, next) => {
res.locals.session = req.session
next()
})
Then in your template you can call it like this.
h3= session.name
Related
I use nestjs to build a REST API.
I have a middleware which loads data from redis cache and should save it in the request object to access it in the controller function.
If i use express as engine it works, but with fastify it doesn't work. The data is undefined in the controller function.
The code looks like:
function mymiddleware(req, res, next) => {
req.data = {...};
next();
};
this is a simple working example:
const fastify = require('fastify')({ logger: true })
fastify.use(function (req, res, next) {
console.log('middy')
req.data = { hello: 'world' }
next();
})
fastify.get('/', (req, res) => {
res.send(`hello ${req.raw.data.hello}`)
})
fastify.listen(3000)
I think that your problem is due to the req object: in middleware (registered using .use you will get the standard Node.js request, instead of augmented HTTPRequest in the fastify handler.
So, you can access the low-level Http request with .raw field.
I am trying to use passport.js to set up authorization in an api. I am having trouble checking if a user is already logged. In expressjs I would do something like:
router.get('/is_logged_in',
passport.authenticate('jwt', { session: false }),
function (req, res, err) {
...
}
that is, in expressjs you can add the middleware passport.authenticate(...),
Can this be done with restify?, for instance if I have the route:
server.get('/is_logged_in', (req, res, next) => {
...
});
Where do I put the middleware? (or is this supposed to be done differently?) I can not add it as a second parameter for what I understand.
I have an Angular app running alongside a NodeJS server.
This code in my server.js file:
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
require('./server/routes/routes')(app, passport);
Seems to be preventing any GET requests to my api, for example:
module.exports = function (app, passport) {
app.get('/api/profile', isLoggedIn, function (req, res) {
res.status(200).json(req.user);
});
When the exported /api/profile handler is changed to a post the request works.
Should the route not overwrite the initial handler? How to achieve this? Can I serve the app for all routes excluding beginning with '/api'?
Move the app.get('*') so it becomes the last route that gets declared:
require('./server/routes/routes')(app, passport);
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist/index.html'));
});
Express checks route handlers in order of their declaration, not in order of their specificity (how well they match a particular request).
I have 3 express.js routes
app.get('/packages/:name', (req, res) => {...});
app.get('/packages/search/', (req, res) => {...});
app.get('/packages/search/:name', (req, res) => {...});
The first and thrid routes are working just fine.
But the second route is never triggert. When I browse to "localhost/packages/search/" it will trigger the first route with res.params.name = "search/"
I can do an "if" to check if its "search/" but i don't think thats a good solution.
Am I doing something wrong?
Routes in express.js are executed in order.
For detail Node.js Express route naming and ordering: how is precedence determined?
I want to pass the environment for Express to a routing module for Express. I want to key off of whether Express is running in development or production mode. To do so, I'm guessing I need to pass app.settings.env somehow to a routing module.
My routing module exports a function for each route. So:
app.get('/search', web.search);
Based upon a previous stackoverflow post, i have tried this:
var web = require('./web')({'mode': app.settings.env});
But node throws an type error (object is not a function).
I'm new to Node and Express. Can I pass a value to an express route and if so, how?
If you web.js looks like this:
module.exports.search = function(req, res, next) {
// ...
};
module.exports.somethingOther = function(req, res, next) {
// ...
};
then by calling
var web = require('./web')({'mode': app.settings.env});
you try to use object (module.exports) as function. Type error here.
You need to convert module.exports to function to pass parameters to it. Like this:
module.exports = function (env) {
return {
// env available here
search: function(req, res, next) {
// ...
},
somethingOther: function(req, res, next) {
// ...
};
};
};