app.js
// Calling Routes
require("./routes")(app);
router folder
index.js
module.exports = function (app) {
app.use("/", require("./all_routes"));
}
all_routes.js
var express = require("express");
var router = express.Router();
router.get("/", function (req, res, next) {
res.render("home/index.html");
});
//About Page
router.get("/about", function (req, res, next) {
res.render("about/index.html");
});
//Contact
router.get("/contact", function (req, res, next) {
res.render("contact/index.html");
});
//product
router.get("/product", function (req, res, next) {
res.render("product/index.html");
});
//product list
router.get("/product/demo-product", function (req, res, next) {
res.render("demo-product/index.html");
});
router.get("/product/request-product", function (req, res, next) {
res.render("request-product/index.html");
});
//service
router.get("/service", function (req, res, next) {
res.render("product/index.html");
});
//service list
router.get("/service/what-we-do", function (req, res, next) {
res.render("what-we-do/index.html");
});
router.get("/service/how-we-do", function (req, res, next) {
res.render("how-we-do/index.html");
});
I am trying to reduce the code in all_routes.js file has same code is repeating again and again
I searched online and trying to create it dynamically but getting no success is there any way I can reduce the line of code as I have given the follow of my code above
If you'd like to cut down on boilerplate of all your get routes, one option is to create an object to map your routes to the files they're loading. Then you can iterate over that object and add the routes to your router.
const routes = {
"/": "home/index.html",
"/about": "about/index.html",
"/contact": "contact/index.html"
// Add others here
}
for (let key in routes) {
router.get(key, function (req, res, next) {
res.render(routes[key]);
});
}
Edit: If your routes are consistent in that the index.html file will always be in the directory named after the part after the last / in your route, you can potentially use an array and some fancy logic. Just don't break the rule!
const routes = [
"/contact",
"/product",
"/product/demo-product",
"/product/request-product"
]
routes.forEach(route => {
const path = /[^/]*$/.exec(route)[0];
router.get(route, function (req, res, next) {
res.render(`${path}/index.html`);
});
})
Related
app.js:
var app = express();
app.use('/my-page', require('./routes/my-page.js'));
my-page.js:
const router = require('express').Router();
router.get('/one', function (req, res, next) {
return res.send('this is /my-page/one');
});
router.get('/my-other-page', function (req, res, next) {
return res.send('this is /my-other-page');
});
How do I make it so my-other-page isn't under my-page, but is instead on the root? I do not want to change app.js because i still want most routes under that page, just one specific one that I want to not have /my-page.
I tried .. in the route but doesnt work. I tried making app from app.js global, but that didn't seem to work either.
Typically you have a routes.js that can import the other routes. (You don't need to, but I think it will better for your structure).
app.js
var app = express();
app.use('/', require('./routes/routes.js'));
routes.js
const router = require('express').Router();
router.use('/my-page', require('./my-page.js'));
router.use('/my-other-page', require('./my-other-page.js'));
Then you split my-page.js and my-other-page.js.
my-page.js
const router = require('express').Router();
// This is /my-page/one
router.get('/one', function (req, res, next) {
return res.send('this is /my-page/one');
});
my-other-page.js
// This is /my-other-page/one
router.get('/one', function (req, res, next) {
return res.send('this is /my-other-page/one');
});
In my Express application I implement routes in routes.ts:
var Router = express.Router();
Router.route('/models/:modelId')
.get(function (req, res) {
service.setParameter(req)
service.get(req,res)
});
Router.route('/models/:modelId')
.post(function (req, res) {
service.setParameter(req)
service.post(req,res)
});
And express.ts:
export const App = express()
App.use(express.json())
App.use(express.urlencoded({ extended: true }))
App.use(helmet())
App.use('/', Router)
At each router call I'd like to execute a piece of code service.setParameter(req) that gets particular parameter from 'params', but I don't want to add to each router method explicitly.
I tried adding it at as middleware before and after Router
App.use('/', Router)
App.use(function(req, res, next){
service.setParameter(req)
next()
})
But if I define it before Router then route hasn't been set yet, and I don't get the parameter I want, and if I define it after, then middleware is not executed.
How can execute service.setParameter(req) in a generic way so that it applies to all the routes?
In express.ts file, you can add a middleware that would do it before mounding the Router, and then just procced forward with next(). You can do it like this:
App.use('/*', (req, res, next) => {
service.setParameter(req);
next();
});
App.use('/', Router)
You need to place your custom middleware between the context path and your router inside app.use(..):
const router = express.Router();
router.post('/', (req, res) => {
service.post(req,res);
});
router.get('/', (req, res) => {
service.get(req,res)
});
app.use('/models', (req, res, next) => {
service.setParameter(req);
next();
}, router);
With above code the middleware will be excecuted for all requests to '/models'.
You can use app.use(async (req,res,next) => {...}) in order to declare a middleware that executes in all the requests, if you want this middleware to be called first, it must be declare before than your routes, the middleware have to call next() in order to continue with the execution flow, if you want to be called at the end of you request, you have to put at the end of your declarations but before of the error middleware, in that approach each route have to call next() at the end of your function.
First approach
const express = require('express');
const app = express();
const router = express.Router();
router.post('/', async (req, res) => {
await service.post(req,res);
});
router.get('/', async (req, res) => {
await service.get(req,res)
});
app.use((req,res,next) => {
console.log("always called");
next();
});
app.use('/',router);
Second approach
const express = require('express');
const app = express();
const router = express.Router();
router.post('/', async (req, res, next) => {
await service.post(req,res);
next();
});
router.get('/', async (req, res, next) => {
await service.get(req,res);
next();
});
app.use('/',router);
app.use((req,res) => {
console.log("always called");
});
Thanks for all the answers, they helped me better understand how routing works on Express.
I found another solution, which I think works best in my case - using Router.all() method:
const setRequest = function(req, res, next){
logger.setRequest(request)
next()
}
Router.route('/models/:model_id')
.all(setRequest)
.get(function (req, res) {service.execute()})
.put(function (req, res) {service.execute()})
How can I insert isLoggedIn as a condition to the get request using router.route?
const controller = require('./controller');
const Router = require('express').Router;
const router = new Router();
function isLoggedIn(req, res, next) {
if (req.isAuthenticated())
return next();
res.redirect('/');
}
router.route('/')
.get((...args) => controller.find(...args))
I assume that the ...args are (req, res, next)
I tried
router.route('/')
.get(isLoggedIn(...args) => controller.find(...args))
But I get
.get((isLoggedIn(...args)) => controller.find(...args))
^
SyntaxError: Unexpected token (
The docs say, that you can assign multiple handlers to one route. Like this:
app.use('/user/:id', function (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}, function (req, res, next) {
console.log('Request Type:', req.method)
next()
})
Source
In your case the coding looks like the following
router.get('/', isLoggedIn, controller.find);
I have the following function that I placed inside a separate js file.
I am trying to use it inside another javascript file that requires passport.js, and I would like to call it using app.use to further modularize my application
var express = require('express');
var router = express.Router();
/* GET welcome page. */
router.get('/home', isLoggedIn, function(req, res, next) {
res.render('home', {
title: 'title',
user : req.user
});
});
// route middleware to make sure
function isLoggedIn(req, res, next) {
// if user is authenticated in the session
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
module.exports = router;
The reason I created it is so I reduce redundancy and not use the following code each time:
app.get('/home', isLoggedIn, function(req, res) {
res.render('home.ejs', {
user : req.user // get the user out of session and pass to template
});
});
However I can't seem to get it to work. is authenticated is undefined although it is in the same folder, and it gives me an error 404 not found when I issue a get. How I can keep it in an external file and still use it? should I also pass it the user argument from where I am calling it?
var express = require('express');
var router = express.Router();
module.exports = function (app, passport){
router.get('/home', isLoggedIn, function(req, res, next) {
res.render('home', {
title: 'title',
user : req.user
});
});
return router;
};
function isLoggedIn(req, res, next) {
// if user is logged in -
if (req.isAuthenticated())
return next();
// if they aren't redirect them to home
res.redirect('/');
}
Am I doing something wrong here, or does express just not support next('route') with .use()?
var express = require('express')
var app = express()
app.use([
function (req, res, next) {
return next('route')
},
function (req, res, next) {
return res.send('sigma')
},
])
app.use(function (req, res, next) {
return res.send('alpha')
})
module.exports = app
This serves the string sigma and should server the string alpha.
Update: just tried this and it didn't work as well.
var express = require('express')
var app = express()
app.use('/', [
function (req, res, next) {
return next('route')
},
function (req, res, next) {
return res.send('sigma')
},
])
app.use('/', function (req, res, next) {
return res.send('alpha')
})
module.exports = app
Update, this too:
var express = require('express')
var app = express()
app.use(function (req, res, next) {
return next('route')
},
function (req, res, next) {
return res.send('sigma')
})
app.use(function (req, res, next) {
return res.send('alpha')
})
module.exports = app
According to the discussion in node issue #2591: since app.use() defines middleware, and not a "route", next('route') is meaningless when used with app.use().
The only difference I can tell between .all and .use is that .use defaults the path to /.
So this works:
var express = require('express')
var app = express()
app.all('/', [
function (req, res, next) {
return next('route')
},
function (req, res, next) {
return res.send('sigma')
},
])
app.all('/', function (req, res, next) {
return res.send('alpha')
})
module.exports = app