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