Parenthesis in Node Express POST Route not found - node.js

I am mocking a POST route in Express for testing MS XRM.
Working Route:
http://localhost:3000/api/data/v8.0/something
app.post('/api/data/v8.0/something', function (req, res) {
res.send({data:'1234A'});
});
Failing Route:
http://localhost:3000/api/data/v8.0/something(ABC)/somethingelse
app.post('/api/data/v8.0/something(ABC)/somethingelse', function (req, res) {
res.send({data:'1234A'});
});

Parentheses in route paths have special meaning, but it looks like you can escape them like this:
app.post('/api/data/v8.0/something[(]ABC[)]/somethingelse', function (req, res) {
res.send({data:'1234A'});
});

Related

How do I automatically return a 404 when a GET path doesn't exist?

I am using NodeJS, Express and Handlebars (template engine) to build a web application. Currently I'm trying to automatically redirect users whenever they enter an URL that does not exist (or whenever they might not have access to it).
The following returns the index page:
router.get('/', (req, res) => {
res.render('index/index');
});
But how do I make something like this:
router.get('/:ThisCouldBeAnything', (req, res) => {
res.render('errors/404');
});
The following example is from Github:
Say that I enter this URL:
https://github.com/thispagedoesnotexist
It automatically returns a 404. How do I implement this in my application?
Thanks in advance.
Use a middleware just after all route handlers to catch non existing routes:
app.get('/some/route', function (req, res) {
...
});
app.post('/some/other/route', function (req, res) {
...
});
...
// middleware to catch non-existing routes
app.use( function(req, res, next) {
// you can do what ever you want here
// for example rendering a page with '404 Not Found'
res.status(404)
res.render('error', { error: 'Not Found'});
});
After all your other routes you can add:
app.get('*', (req, res) => {
res.render('errors/404');
});
Alternately, you can use a middleware function after all your other middleware and routes.
app.use((req, res) => {
res.render('errors/404');
});
So you might end up with something that looks like:
//body-parser, cookie-parser, and other middleware etc up here
//routes
app.get('/route1', (req, res) => {
res.render('route1');
});
app.get('/route2', (req, res) => {
res.render('route2');
});
//404 handling as absolute last thing
//You can use middleware
app.use((req, res) => {
res.render('errors/404');
});
//Or a catch-all route
app.get('*', (req, res) => {
res.render('errors/404');
});
I see that you have express tagged. All you have to do is include a default handler that includes
res.status(404).render('404template')
For example
app.get('*', (req, res,next) => {
res.status(404).render('error.ejs')
});

Defining root and error routes in NodeJs/Express

I defined some routes for my application. Like
app.get('/page1', function (req, res) {
res.render('page1');
});
app.get('/page2', function (req, res) {
res.render('page2');
});
and if the route is missing or wrong, the application should always redirect to another page. I want to define a root route:
app.get('/', function (req, res) {
res.render('notFound'); // redirect to a 404 template
});
and what do I have to define to cover all the error or missing pages?
When having '/page1/abcdefgh' and '/fooBar' both routes should redirect to the res.render('notFound'); template.
To handle a 404 place a * route-handler below all pre-defined routes. So if none of your predefined routes will match (like /page1 or /page2), the * will get triggered.
// Will match /page1
app.get('/page1', function (req, res) {
res.render('page1');
});
// Will match /page2
app.get('/page2', function (req, res) {
res.render('page2');
});
// Will be triggered if nothing above got a match
app.get('*', function (req, res) {
res.render('notFound'); // redirect to a 404 template
});

Difference between adding route keyword in defining route in Express

What is the difference between
router.route('/create')
.post(validate(hotelValidation.createHotel), function (req, res) {
and simply
router.post('/create', validate(hotelValidation.createHotel), function (req, res) {
Are these the same? What does the route keyword accomplish here?
Are these the same? What does the route keyword accomplish here?
Here it accomplishes nothing. But you could do:
app.route('/some/very/long/path/that/you/dont/want/to/duplicate/risking/errors')
.get(function (req, res) {
})
.post(function (req, res) {
})
.put(function (req, res) {
});
Instead of:
router.get('/some/very/long/path/that/you/dont/want/to/duplicate/risking/errors', function (req, res) {
})
router.post('/some/very/long/path/that/you/dont/want/to/dpulicate/risking/errors', function (req, res) {
})
router.put('/some/very/long/path/that/you/dont/want/to/dulpicate/risking/errors', function (req, res) {
});
router.route(path) creates an instance of a single Route for the given path.
Using router.route(path) is a recommended approach to avoiding duplicate route naming and thus typo errors.
router.[method] like "post" and "get" These are functions which you can directly call on a route to register a new handler for the method on the route.

how can I be more specific with express router params

I currently have a few router routes
router.route('/invite/token/:inviteToken')
.get(function (req, res) {
res.status(200).json(req.invite);
});
router.route('/invite/:inviteId')
.get(function (req, res) {
res.status(200).json(req.invite);
});
And the following simple router params:
router.param('inviteToken', function (req, res, next, inviteToken) {
console.log('inviteToken');
// populate req.invite
next();
});
router.param('inviteId', function (req, res, next, inviteId) {
console.log('inviteId');
// populate req.invite
next();
});
However when I try to fetch an invite by token the inviteId param handler is always triggered first with the literal value "token". Is there an issue with the way I've set up the routes and params?
Update 1 For more clarification
Route order definition matters, so the best practice is to go from most specific to most grabby.
app.get('/invite/token/:token', tokenHandler);
app.get('/invite/:inviteId', inviteHandler);
where tokenHandler and inviteHandler are appropriately formatted callback functions.

Passing extra parameters to route handlers in Express

I'm relatively new to Express, and I'm looking for a way to make routes more reusable. In my app, I will have quite a few routes that can be passed to a generic handler, but will have different templates.
Example:
app.get('/about', function(req, res) {
res.render('about.html');
});
app.get('/', function(req, res) {
res.render('home.html');
});
While this example is contrite, I have 30+ such routes. What I would like to be able to do is something like this:
app.get('/about', generic.render('about.html'));
or otherwise somehow pass the template name to the function that returns res.render Is this possible in Express? All of my attempts to work around this result in variables being undefined.
I would prefer to not do something like this, tightly coupling my route parameters and template names:
app.get('/:template', function(req, res) {
res.render(req.params.template + '.html');
});
You could just make a a simple middleware that does this for you. Example:
function simpleRender(file, opts) {
opts || (opts = {});
return function(req, res) {
res.render(file, opts);
};
}
Then just use it like:
app.get('/about', simpleRender('about.html'));
app.get('/', simpleRender('home.html'));
This is how I do it:
const handler = (req, res, template) => {
res.render(template)
}
app.get('/about', (req, res) => {
handler(req, res, 'about.html')
})
This is a best practice for me
app.get('/:template',(req, res, next) => {
res.locals = `${template}.html`;
next();
},
renderMethod
);
function renderMethod(req, res){
res.render(res.locals)
}

Resources