How do I fetch the syntax/name of the current route handler, ignoring the current specific param values?
e.g.:
app.get('/users/:id', (req, res) => {
let route = ?
console.log(route) // --> "/users/:id"
})
(Question 2 - can I do this in a middleware function?)
The correct answer is req.route.path
e.g.
1. Call directly from main file (app.js / index.js):
app.get('/admin/:foo/:bar/:baz', async (req, res) => {
console.log(req.originalUrl);
console.log(req.url);
console.log(req.path);
console.log(req.route.path); // this one is your answer
console.log(req.baseUrl);
console.log(req.hostname);
res.sendStatus(200);
});
API call:
http://localhost:3000/admin/a/b/c
Output
/admin/a/b/c (originalUrl)
/admin/a/b/c (url)
/admin/a/b/c (path)
/admin/:foo/:bar/:baz (route.path)
<nothing> (baseUrl)
localhost (hostname)
2. Call from a module:
app.js
const express = require('express');
const app = express();
...
const users = require('./users');
app.use('/api/users', users);
users.js
const express = require('express');
const router = express.Router();
...
router.get('/admin/:foo/:bar/:baz', async (req, res) => {
console.log(req.originalUrl);
console.log(req.url);
console.log(req.path);
console.log(req.route.path); // this one is your answer
console.log(req.baseUrl);
console.log(req.hostname);
res.sendStatus(200);
});
API call:
http://localhost:3000/api/users/admin/a/b/c
Output
/api/users/admin/a/b/c (originalUrl)
/admin/a/b/c (url)
/admin/a/b/c (path)
/admin/:foo/:bar/:baz (route.path)
/api/users (baseUrl)
localhost (hostname)
You can see below example for information about req object that you get.
/users can be obtained from req.baseUrl and :id can be obtained from req.params.id
app.use('/admin', function (req, res, next) { // GET 'http://www.example.com/admin/new?a=b'
console.dir(req.originalUrl) // '/admin/new?a=b' (WARNING: beware query string)
console.dir(req.baseUrl) // '/admin'
console.dir(req.path) // '/new'
console.dir(req.baseUrl + req.path) // '/admin/new' (full path without query string)
next()
})
Related
Anyone know the solution? When I console log the variable it shows undefined. I need to pass the req.body (name and email) element to second post route which is "/company" route. I have two forms and I want to pass the first form data to second form the "/company" route form. then the two form data will be stored in mongoDb. I tried everything but I got only undefined in second route the "/company" route
import express from "express";
const app = express();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
//Assign the name and email to variable and sent to last route
const middleware = (req, res, next) => {
const { name, email } = req.body;
let nameNew = name;
let emailNew = email;
// add nameNew and emailNew to req object
// so that it can be access in other routes
req.nameNew = nameNew;
req.emailNew = emailNew;
// console.log(nameNew);
// console.log(emailNew);
next();
};
//Get name email from user input and sent it middleware
app.post("/", middleware, (req, res, next) => {
const { name, email } = req.body;
res.send("Home route");
});
//Get the name and email from middleware
app.post("/company", middleware, (req, res) => {
// console.log(nameNew);
// access req.body without middleware
// console.log(req.body);
// access req.body using middleware
console.log(req.nameNew);
console.log(req.emailNew);
res.send("Company route");
});
//Server running
app.listen(4000, () => {
console.log(`Server Started `);
});
When your request gets into your app.post("/") it sets the nameNew variable inside your middleware scope. You cannot access this variable in your other routes.
If you want to access variables shared from your middleware you can use res.locals : https://expressjs.com/en/api.html#res.locals
You can't pass data from route 1 to route 2 through middleware.
It passes through the middleware and sets the variables but on your res.send theses variable will disappear. These are just set for the "instance" of the incoming request and on res.send will be destroyed.
You would need to send back data to the front-end to pass it back to your API for route 2.
You can call functions from your route definition :
app.get('/getUserInfos', isLoggedIn, (req, res) => {
return getUserInfos(res);
});
This way you can process your data and save it however you want.
Also, looks like you can chain functions there : https://stackoverflow.com/a/62723674/12343548
I use req.app.locals to send the data in first route to second route. Anyone want to do this type of program in future Here is the solution.
const express = require("express");
const app = express();
const path = require("path");
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
const middleware = (req, res, next) => {
const { name, email } = req.body;
req.app.locals.nameNew = name;
req.app.locals.emailNew = email;
next();
};
app.get("/", (req, res) => {
res.sendFile(path.join(__dirname + "/index.html"));
});
app.post("/", middleware, (req, res) => {
const { name, email } = req.body;
res.send("Home Route");
});
app.get("/company", (req, res) => {
res.sendFile(path.join(__dirname + "/company.html"));
console.log(req.app.locals.nameNew);
console.log(req.app.locals.emailNew);
});
app.post("/company", (req, res) => {
console.log(req.app.locals.nameNew);
console.log(req.app.locals.emailNew);
res.send("Company Route");
});
//Server running
app.listen(4001, () => {
console.log(`Server Started `);
});
const express = require('express');
const app = express();
app.use('/', (req, res,next) => {
res.send('Bid Request GET');
});
app.get('/', (req, res) => {
res.send('Bid T');
});
app.listen(3000, () => console.log('app listening on port 3000!'))
I am beginner in node js. When I run the code it only shows app.use() response not app.get() response.
I am confused. i tried next() method also, but not working. how to solve this?
Main reason behind this is because you've already sent the response here:
app.use('/', (req, res,next) => {
res.send('Bid Request GET');
});
You can only send one response per request.
Each app.use middleware is a function with access to request, response, next parameter. when next function is invoked, it executes the middleware succeeding the current middleware.
You can also pass data from one middleware to another by creating variable in request or response. For Ex.
app.use('/', (req, res, next) => {
if(req.body.token !== 'abc') return res.sendStatus(503)
let someData = () => { .... SomeFunctionCode ... }
req.myVarible = someData // or res.myVariable = someData or anything
next()
})
But the recommended way of passing value is through res.locals.myVariable
Here is full example:
app.use('/', (req, res, next) => {
if(req.body.token !== 'abc') return res.sendStatus(503)
let someData = () => { .... SomeFunctionCode ... }
req.locals.myVarible = someData
next()
})
app.get('/', (req, res) => {
res.send(res.locals.myVariable)
})
Need some help or any clue including/requiring dynamic routes at runtime in express, its confusing but i try my best.
This is just an example of app routes configuration right now
app.use('/', require('./routes/public'));
app.use('/u', require('./routes/user'));
app.use('/a', require('./routes/admin'));
for example require('./routes/public') will include something like this
router.get('/', home.index);
router.get('/faq', faq.index)
also require('./routes/user') will include this
router.get('/dashboard', user_home.index);
router.get('/accounts', user_acc.index)
also require('./routes/admin')
router.get('/dashboard', adm_home.index);
router.get('/accounts', adm_acc.index)
i have installed passportjs so its easy to check if the user is authenticated, also if it is, user contains 1 property type, eg: 1 = user, 2 = admin.
req.user.type = 1 or 2, req.isAuthenticated()...
what i need is inject depending user type 1 or 2, require('./routes/user') or require('./routes/admin') at runetime, cos i dont want to declare invalid routes for an user type user example including admin, or backwards.
Right now, all routes are visible or valid but i need to check every controller for user type, also i dont want the '/a' OR '/u' routes prefix.
All routes must be under '/'.
Request runs to first matched path. You can render page, throw error or call next to get next middleware. Below some router examples.
'use strict'
var express = require ('express');
var app = express();
var publicRouter = express.Router();
publicRouter.get('/', (req, res) => res.send('ROOT'));
publicRouter.get('/account', function (req, res, next) {
if (!is-user)
res.send('Hello guest')
else
next();
});
var userRouter = express.Router();
function isUser (req, res, next) {
// return next() on user logon, and error otherwise
return next();
}
userRouter.use(isUser);
userRouter.get('/dashboard', (req, res) => res.send('/dashboard'));
userRouter.get('/account', (req, res) => res.send('Hello user'));
var adminRouter = express.Router();
function isAdmin (req, res, next) {
// return next() on admin logon, and error otherwise
return next(new Error('Access denied'));
}
adminRouter.get('/manage', (req, res) => res.send('/manage'));
app.use(publicRouter);
app.use(userRouter);
app.use('/admin', isAdmin, adminRouter); // "/admin/manage", not "/manage"
// error handler
app.use(function (err, req, res, next) {
res.send(err.message);
});
app.listen(2000, () => console.log('Listening on port 2000'));
Another way is
app.get('/', do-smth);
app.get('/dashboard', isUser, do-smth);
app.get('/manage', isAdmin, do-smth);
I have a middleware that I want to be applied only when the http method is post.
The following works fine, but I get the feeling there is a better way:
'use strict'
const express = require('express'),
router = express.Router()
router.use((req, res, next) => {
if (req.method === 'POST') {
// do stuff
}
return next()
})
module.exports = router
I'd like to do something like this, but it doesn't work:
'use strict'
const express = require('express'),
router = express.Router()
router.post((req, res, next) => {
// do stuff
return next()
})
module.exports = router
You can use * symbol:
const express = require('express')
const app = express();
app.post('*', (req, res, next) => {
console.log('POST happen')
next();
})
app.post('/foo', (req, res) => {
res.send('foo');
});
app.post('/bar', (req, res) => {
res.send('bar');
});
app.listen(11111);
This will respond with "foo" string on POST /foo and with "bar" string on POST /bar but always log "POST happen" to console.
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