Still wondering how to get Express to ignore matching route - node.js

I have this verbatim:
router.get('/top_level_questions,', function (req, res) {
res.json({success:true});
});
router.get('/:id', function (req, res) {
res.json({success:true});
});
what's happening is that a request to
/top_level_questions
will match the /:id handler. What is the official way to prevent that from happening>

The code:
router.get('/top_level_questions,', function (req, res) {
res.json({success:true});
});
Should be:
router.get('/top_level_questions', function (req, res) {
res.json({success:true});
});

Related

Is it possible to dynamically use a route part to call passport strategy?

Currently, I have the following code for many more oath provider:
// facebook
router.get("/facebook", passport.authenticate("facebook", { scope: ["email"] }));
router.get("/facebook/callback", passport.authenticate("facebook"), (req, res) => {
console.log(chalk.blue("went into facebook callback"));
res.redirect("http://localhost:3000/profile");
});
// github
router.get("/github", passport.authenticate("github"));
router.get("/github/callback", passport.authenticate("github"), (req, res) => {
console.log(chalk.blue("went into github callback"));
res.redirect("http://localhost:3000/profile");
});
Is there a way to unify that into an abstracted route? I.e. something like
// github
router.get("/:provider", passport.authenticate(:provider));
router.get("/:provider/callback", passport.authenticate(:provider), (req, res) => {
console.log(chalk.blue("went into {:provider} callback"));
res.redirect("http://localhost:3000/profile");
});
Update:
The following piece of code does what I want. Thx to #Usman Abdur Rehman.
function callbackDistributer(req, res, next) {
console.log(req.params);
global.provider = req.params.provider;
next();
}
router.get(
"/:provider/callback",
callbackDistributer,
(req, res, next) => {
passport.authenticate(global.provider)(req, res, next);
},
(req, res) => {
console.log(chalk.red("went into: " + global.provider));
res.redirect("http://localhost:3000/profile");
}
);
Have a middleware function going before the passport.authenticate middleware
function ownMiddleware(req,res,next){
global.provider = req.params.provider
next()
}
and then use it in the route handler as
router.get("/:provider/callback", ownMiddleware ,passport.authenticate(global.provider), (req, res) => {
console.log(chalk.blue("went into {:provider} callback"));
res.redirect("http://localhost:3000/profile");
});
I think it should work

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

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 do i send multiple arguments to an Express.js route?

Let say I want to add multiple arguments.
Here's the code
function firstArgument(req, res, next) {
// Do something
}
function secondArgument(req, res, next) {
// Do something
}
app.get('/something', firstArgument, secondArgument, function(req, res, next) {
// Is it possible to do this?
});
Is it possible? if so how does it works? Can anyone explain it to me.
Thank you
All the answers are in the express docs - http://expressjs.com/es/guide/routing.html
To summarize, for your scenario you can use:
var cb0 = function (req, res, next) {
console.log('CB0')
next()
}
var cb1 = function (req, res, next) {
console.log('CB1')
next()
}
app.get('/example/d', [cb0, cb1], function (req, res, next) {
console.log('response will be sent by the next function ...')
next()
}, function (req, res) {
res.send('Hello from D!')
})
or, without the second method.
var cb0 = function (req, res, next) {
console.log('CB0')
next()
}
var cb1 = function (req, res, next) {
console.log('CB1')
next()
}
app.get('/example/d', [cb0, cb1], function (req, res) {
res.send('Hello from D!')
})
Regarding how it works - it simply runs all the methods one after the other: when the next() method is called, the next method is being called.

Express/Passport: adminpanel authorization

Is there any way to make authorization system like this:
app.get('/admin/*', function (req, res) {
/*checks if user authorised, if not throws an error, if yes opens requested page*/
});
app.get('/admin/item', function (req, res) {
/*blah-blah-blah*/
});
app.get('/admin/category', function (req, res) {
/*blah-blah-blah*/
});
As an example I logged in and want to open /admin/item page.
I can simply get what do I want by this way, but this way generates more code:
app.get('/admin/item', function (req, res) {
/*authorization check*/
/*blah-blah-blah*/
});
app.get('/admin/category', function (req, res) {
/*authorization check*/
/*blah-blah-blah*/
});

Resources