Express.js Routing wrong route - javascript

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?

Related

How to render multiple static files in express?

I am trying to use express to render a few different html files from my public folder. These are all static files. I also want to render a 404 page if a route is an invalid route is called. Here is my code.
const express = require("express")
const app = express()
app.use(express.static("public"))
app.get("/", (req, res) => {
res.render("index")
})
app.get("/about", (req, res) => {
res.render("about")
})
app.get("/contact-me", (req, res) => {
res.render("contact-me")
})
app.get("*", (req, res) => {
res.status(404).send("404 for all pages not defined in routes")
})
app.listen(8080)
The first route to render index.html works and the 404 status works, but all the other routes give me an error of "No default engine was specified and no extension provided." I tried added an ejs view engine, but the code still doesn't work. All html files are named properly and live in the "public" folder. Any help on this would be amazing! Thanks much!
You need to use handlebars for handling it. To see an example check this repo

Why is Express redirecting infinitely redirecting me?

I am trying to setup a multi language website with Express and NodeJs. My problem is I get redirected what it feels like 100 times and my browser is giving me a error that the webpage is not working because it redirected me too many times.
app.js
app.use('/', (req,res,next) => {
res.redirect('/en-US');
next();
});
app.use('/:lang', indexRouter);
app.use('/:lang/users', usersRouter);
index.js (indexRouter)
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
res.render('index');
});
module.exports = router;
The problem is that this route handler:
app.use('/', (req,res,next) => {
res.redirect('/en-US');
next();
});
will get hit for not only /, but also /en-US. app.use() matches any route handler for which the path is equal to or a subset of the requested path. So, the browser requests "/", you redirect to "/en-US", which then redirects to "/en-US" and so on, an infinite loop.
I don't know the overall URL design of your site to know what the best overall solution is. You can prevent the infinite redirect loop by just changing app.use() to app.get():
app.get('/', (req,res,next) => {
res.redirect('/en-US');
});
But, that will make the redirect only work for GET requests which may or may not be OK. If you want all HTTP verbs to redirect, you could change to app.all():
app.all('/', (req,res,next) => {
res.redirect('/en-US');
});
The important thing to understand here is that app.get(), app.post(), app.all(), etc... all require an exact match for the URL path, whereas app.use() just requires a subset match. This is a little understood aspect of the Express design.
In addition, remove the call to next() after you do res.redirect(). At that point, you've sent the response, you don't want any other request handlers to see the request. You're done with routing.
under your app.js
Try using
app.use('/', router )
How about you try dealing with the '/' route through the app.js directly instead of index.js

Globally set dynamic pug variables

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

Override app.get('*', func) route in express

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).

Endpoints clashing in different route files expressJS

I cant seem to use the same endpoint in different route files.
index.js:
var users = require('./routes/users.js');
var orders = require('./routes/orders.js');
app.use('/users', users);
app.use('/orders', orders);
routes/users.js:
baseDep.router.get('/', function (req, res) {
res.json("This is the users route");
});
routes/orders.js
baseDep.router.get('/', function (req, res) {
res.json("This is the orders route");
});
localhost:3000/orders --> This is the users route
localhost:3000/users --> This is the users route
The second one works as expected.
The first one seems to using the endpoint in the users route file.
Can someone help figure out what I need to do?
If you have a look at the documentation for express app.use() method, it tells you that you need to use next() function in the middleware so that is can move on: https://expressjs.com/en/4x/api.html#app.use
For example:
baseDep.router.get('/', function (req, res, next) {
res.json("This is the users route");
next();
});

Categories