unable to get params from middleware into route - node.js

app.js
const adminRoutes = require('./routes/admin');
app.use('/admin/customer/:customerId', (req, res, next) => {
console.log('middleware id=', req.params.customerId);
next();
}, adminRoutes);
and here is routes/admin.js
const express = require('express');
const router = express.Router();
router.post('/user', (req, res) => {
console.log('route id=', req.params.customerId);
res.json(req.params);
});
module.exports = router;
I am getting following output
middleware id= 1
route id= undefined
while expected output is
middleware id= 1
route id= 1

You need to use Router options property mergeParams if you want to access params from the parent router.
const express = require('express');
const router = express.Router({mergeParams:true});
router.post('/user', (req, res) => {
console.log('route id=', req.params.customerId);
res.json(req.params);
});
module.exports = router;

You can try this:
You can directly call your route without using another callback and it should work
app.js
const adminRoutes = require('./routes/admin');
app.use('/admin/customer/:customerId',adminRoutes);
If it does't work then you will have to set the params in request object before using your routes

Related

Cannot enter router get in express

I am trying to use routers in my Node js application. I cannot execute router.get functiom
In the main file which is server.js I used this script
// Routes
app.use('/api/v1/stores', require('./routes/stores'));
But in the route file which is stores.js, I cannot enter the router.get function and execute it
const express = require('express');
const router = express.Router();
console.log("I can reach this point")
router.get('/', (req, res) => {
console.log("I can not reach this point")
res.send('app/about');
});
module.exports = router;
That's because new express version 4.17.* is different when handling routes. try,
const express = require('express');
const app = express();
app.get('/', (req, res) => {
res.send('app/about');
});
module.exports = app;
For more details: https://expressjs.com/en/guide/routing.html
you can try this way also, in your store.js file create something like this.
module.exports = app => {
app.get('/', (req, res) => {
res.send('app/about');
});
}
and add this require to server.js
require('./store')(app);

I cannot get /users json

I'm new to express and node js, I recently learned how to write API for express but at the end, I get some sort of problem which not resolved by me after several tries. I could not get a response on localhost:8080/users
src/routes/users.js
const { Router } = require("express");
const router = Router();
const getUsers = (req, res) =>
res.send(Object.values(req.context.models.users));
const getUser = (req, res) =>
res.send(req.context.models.users[req.params.userId]);
router.get("/users/", getUsers);
router.get("/users/:userId", getUser);
module.exports = router;
src/routes/index.js
const user = require("./user");
const message = require("./message");
module.exports = {
user,
message
};
src/index.js
const express = require("express");
const app = express();
// Custom Modules
const routes = require("./routes");
const models = require("./models");
// Application-Level Middleware Starts
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use((req, res, next) => {
req.context = {
models,
me: models.users[1]
};
console.log(req.context.models.users);
next();
});
// Used Routes
app.use("/users", routes.user);
app.use("/messages", routes.message);
// App Listning to HTTPS Module
app.listen(process.env.PORT);
You need to fix your endpoints in users.js:
router.get("/", getUsers);
router.get("/:userId", getUser);
The reason is because of app.use("/users", routes.user); in your index.js, where the endpoint for users is set. If you leave /users/ in users.js it would be localhost:8080/users/users/. Same problem might be with /messages.

How to app use all routes from different file

I'm trying to separate my routes, previously i'm including them to my app.js
/backend/app.js
const express = require("express");
const router = require("./routes");
const status = require("./routes/status");
const register = require("./routes/register");
const login = require("./routes/login");
app.use('/', router);
app.use('/status', status);
app.use('/login', login);
app.use('/register', register);
I realized its not ideal since i am adding more and more routes later on and the app.js will be polluted with them
What i want to do now is just to import an index.js to app.js and basically this index have all the routes needed
/backend/routes/index
const routes = require("express").Router();
const root = require("./root");
const status = require("./status");
const register = require("./account/register");
const login = require("./account/login");
routes.use("/", root);
routes.use("/login", login);
routes.use("/register", register);
routes.use("/status", status);
and now in the app.js i can just include the index
const routes = require("./routes");
app.use('/', routes);
but its not working im getting 404 error when trying to request to login route
im exporting them like this
module.exports = routes;
In your app.js
app.use('/', require('./backend/routes/index'))
Then, in your routes/index
import express from 'express'
const router = express.Router()
// GET /
router.get('/', function (req, res) {
})
// GET /countries
router.get('/countries', (req, res, next) => {
})
// POST /subscribe
router.post('/subscribe', checkAuth, generalBodyValidation, (req, res, next) => {
})
// All routes to /admin are being solved in the backend/routes/admin/index file
router.use('/admin', require('./backend/routes/admin/index'))
module.exports = router
Your admin/index file can be
import express from 'express'
const router = express.Router()
// POST /admin/login
router.post('/login', (req, res, next) => {
})
module.exports = router
With this, you will be able to perform a POST request to /admin/login.
Hope this solves your problem, if it does mark my answer as correct, if not tell me what went wrong and I will solve it :D

Express Middleware Issue

On routes/index.js it works fine if I leave the module.exports = routes;
But If I change it to the following to allow multiple files then I get a middleware error:
module.exports = {
routes
};
var app = express();
const routes = require('./routes');
const port = process.env.PORT || 3000;
app.use(bodyParser.json());
app.use('/', routes);
app.get('/', (req, res) => {
res.send('Please visit: http://domain.com');
}, (err) => {
res.send(err);
});
//routes/index.js
const routes = require('./MainRoutes');
module.exports = routes;
//routes/Main Routes.js
const routes = require('express').Router();
routes.post('/main', (res, req) => {
//code here works
});
module.exports = routes;
The error is: Router.use() requires middleware function but got a ' + gettype(fn));
MainRoutes.js exports the express router object, which middleware will understand just fine if you do
module.exports = routes; // routes/index.js
However, when you do
module.exports = {
routes
};
You are now nesting that router object in another object, which middleware can't understand.
In your main server file you can do
const {routes} = require('./routes');
to get the router object properly.
Modify the routes/index.js as:
const routes = require('express').Router();
routes.use('/main', require('./MainRoutes'));
// Put other route paths here
// eg. routes.use('/other', require('./OtherRoutes'))
module.exports = routes;
Modify the Main Routes.js as:
const routes = require('express').Router();
routes.post('/', (res, req) => {
// route controller code here
});
module.exports = routes;
Hope this helps you.

NodeJS / ExpressJS check valid token parameter before routing

I have the following app code:
(app.js)
var express = require('express')
, app = express()
, port = process.env.PORT || 8082
app.use(require('./controllers'))
app.use(function(req, res, next) {
res.send('Test')
next()
})
app.listen(port, function() {
console.log('Listening on port ' + port)
})
and two controllers:
(index.js)
var express = require('express')
, router = express.Router()
router.use('/projects', require('./projects'))
module.exports = router
(projects.js)
var express = require('express')
, router = express.Router()
router.get('/:id', function(req, res, next) {
res.json({project: req.params.id})
})
module.exports = router
This works but now I have to check my url for a valid token.
My url looks like http://server/api/projects?token=abc or http://server/api/projects/:id?token=abc
If the token is not valid no projects (or other controllers) should be load / shown.
What is the best way to handle this and where (in app.js or controllers/index.js)?
Use a middleware.
app.use(function (req, res, next) {
if (checkToken(req.query.token) {
return next();
}
res.status(403).end("invalid token");
});
app.use(require('./controllers'))
You can do this validation inside your route function or you can use a middleware that validates the param and then do some logic.
var express = require('express')
, router = express.Router()
function validate(req,res,next) {
if(req.params.id) // some logic
else other stuff
next();
}
router.get('/:id', validate, function(req, res, next) {
res.json({project: req.params.id})
})
module.exports = router

Resources