"next('route')" doesn't work with ".use()" - javascript

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

Related

Execute middleware on every route call

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

creating dynamic routes using nodejs

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

use next('route') and get 'undefined' response in next route in express

const express = require('express')
const app = express()
app.get('/user/:uid', (req, res, next) => {
if (req.params.uid === 'lai9fox') next('route')
else next()
}, (req, res, next) => {
res.send(`<h1>hello, ${req.params.uid}</h1>`)
})
app.get('/user/:id', (req, res, next) => {
res.send(`<h1>Welcome you, ${req.params.uid} !</h1>`)
})
app.listen(3000, () => console.log('server is running at port 3000...'))
When I visit http://localhost:3000/user/lai, it correctly shows:
hello, lai
But when I visit http://localhost:3000/user/lai9fox, it shows:
Welcome you, undefined!
What's go wrong?
you need to change the req.params.uid for id
app.get('/user/:id', (req, res, next) => {
res.send(`<h1>Welcome you, ${req.params.id} !</h1>`)
})

My route wont render

my studies/add wont render. I get "CastError: Cast to ObjectId failed for value "add" at path "_id" " error. I just dont get it, nothing seems to work the way I would expect. Im quite new to express. I tried all kind of different things but it just wont render /studies/add
my studies route `
const express = require('express')
const router = express.Router()
const Studies = require('../models/studies')
router.get('/', (req, res) => {
Studies.find({}, (err, studies) => {
studies.sort(function (a, b) {
return new Date(b.endDate) - new Date(a.endDate)
})
if (err) {
console.log(err)
} else {
res.render('studies', {
studies
})
}
})
})
router.get('/:id', function (req, res) {
Studies.findById(req.params.id, function (err, studies) {
if (err) {
console.log(err)
} else {
res.render('course', {
studies
})
}
})
})
router.get('/add', function (err, req, res) {
if (err) {
console.log(err)
}
res.render('addstudy')
})
module.exports = router
`
my app.js file
const express = require('express')
const bodyParser = require('body-parser')
const path = require('path')
const config = require('./config/database')
const mongoose = require('mongoose')
const Studies = require('./models/studies')
const session = require('express-session')
const passport = require('passport')
// const flash = require('connect-flash')
const app = express()
mongoose.connect(config.database)
let db = mongoose.connection
// Check connection
db.once('open', function () {
console.log('Connected to MongoDB')
})
// Check for DB errors
db.on('error', function (err) {
console.log(err)
})
const logger = function (req, res, next) {
console.log('loogging..')
next()
}
app.set('views', path.join(__dirname, 'views'))
app.set('view engine', 'ejs')
// Body Parser Middleware
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(logger)
// Passport Config
require('./config/passport')(passport)
// Passport Middleware
app.use(passport.initialize())
app.use(passport.session())
// Express Session Middleware
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true
}))
// Express Messages Middleware
/* app.use(require('connect-flash')())
app.use(function (req, res, next) {
res.locals.messages = require('express-messages')(req, res)
next()
}) */
app.use(express.static('public'))
app.get('*', function (req, res, next) {
res.locals.user = req.user || null
next()
})
app.get('/', (req, res) => {
Studies.find({}, (err, studies) => {
console.log(studies)
if (err) {
console.log(err)
} else {
res.render('index', {
name: studies[0].name,
description: studies[0].description
})
}
})
})
let studies = require('./routes/studies')
let work = require('./routes/work')
let about = require('./routes/about')
let users = require('./routes/users')
app.use('/studies', studies)
app.use('/work', work)
app.use('/about', about)
app.use('/users', users)
app.listen(3002, () => {
console.log('started on 3002')
})

Express use function

The below code not functioning as expected
var express = require('express');
var app = express();
app.use(function(req, res, next) {
console.log('first text');
next();
}, function (req, res, next) {
console.log('secondText');
res.end()
}).listen(3000)
app.use([path,] function [, function...])
Mounts the specified middleware function or functions at the specified path. If path is not specified, it defaults to '/' in express documentation but I can't run the second function, not sure why. When I try localhost:3000 in Firefox I receive Cannot GET /
This code is working, but previously it wasn't working:
var express = require('express');
var app = express();
app.use(function(req, res, next) {
console.log("one");
next();
})
.use(function(req,res,next){
console.log("second");
res.end()
})
.listen(3000)
Could it be because of the missing .?
var express = require('express');
var app = express();
app.use(function(req, res, next) {
console.log('first text');
next();
}, function (req, res, next) {
console.log('secondText');
}).listen(3000) //Was missing a period

Categories