I'm running into a strange issue. The first route is working, but the parameterized route returns a 404 error.
var express = require('express');
var router = express.Router();
router.route('/')
.get(function (req, res, next) {
res.send('A list of vehicles.');
})
.post(function (req, res, next) {
res.send('You added a vehicle!');
});
router.route('/:id')
.get(function (req, res, next, id) {
res.send('Vehicle: ' + id);
})
.put(function (req, res, next, id) {
res.send('You edited vehicle: ' + id);
});
If I add this route:
router.route('/test')
.get(function (req, res, next) {
res.send('This is a test.');
});
...I can hit that endpoint. This also seems to work with another router I'm using, which is using router.get(path, function) and router.post(path, function) instead of the router.route(path).get()... methodology.
Am I missing something obvious here? I'm using Express ~4.12.
Gah, I'm an idiot. Just figured this out. I saw an example that used this function signature:
.get(function (req, res, next, id) {
res.send('Vehicle: ' + id);
})
This apparently doesn't work. I'm not sure if the http methods check the arity of the function, but this did work:
.get(function (req, res, next) {
res.send('Vehicle: ' + req.params.id);
})
I don't remember where I saw that example, but hopefully this helps someone.
Related
I am trying to pass some predefined functions in the callback of app.post() method. I am getting next is not defined error. Below is my code. Please suggest where I am doing wrong or am I missing any concept here?
var express = require('express');
var app = express()
app.post('/api/signup', function(req, res) {
validateParams(req, res, next),
dbCall(req, res, next),
sendResponse(req, res)
})
where I have each function defined and imported and returning next() after my process.
my validateParams function is below :
validateParams = function(req, res, next) {
console.log("at validator ", req);
next();
}
module.exports = validateParams;
my dbCall function is below :
dbCall = function(req, res, next) {
console.log("at dbCall ", req);
next();
}
module.exports = dbCall;
my sendResponse function is below :
sendResponse = function(req, res) {
console.log("at dbCall ", res);
res.send("Response sent successfully");
}
module.exports = sendResponse;
You probably forgot to add the next argument in your callback.
app.post('/api/signup', function(req, res, next) {
validateParams(req, res, next),
dbCall(req, res, next),
sendResponse(req, res)
})
I think you are trying to use validateParams(req, res, next) and dbCall(req, res, next) as middleware functions. In this case, you need something like this:
const validateParams = (req, res, next) => {
// do stuff here
next();
}
const dbCall = (req, res, next) => {
// do stuff here
next();
}
app.post('/api/signup', validateParams, dbCall, function(req, res) {
sendResponse(req, res)
})
You can read more here
So this logs to my console:
app.use(function (req, res, next) {
console.log(req.method)
console.log('why not working?')
})
But this doesn't:
app.post(function (req, res, next) {
console.log(req.method)
console.log('why not working?')
})
Both demonstrate that the HTTP method is a POST
What am I missing?
app.post expect path as first parameter.
See more about it http://expressjs.com/en/4x/api.html#app.post.method
For example:
app.post('/', function (req, res) {
res.send('POST request to homepage');
});
In app.use path - optional argument, but in app.post it is required.
I am trying to implement a middleware that will check if a user is authenticated before the server delivers a page. Although it looks like the process of doing this is simple, node is throwing an error which says "Can't set headers after they are sent".
My router's code is:
module.exports = function(app) {
app.get('/', checkAuth, require('./myAuthenticatedPage').get);
app.get('/login', require('./myLoginPage').get);
};
The myAuthenticatedPage.js:
exports.get = function(req, res) {
res.render('index');
};
The myLoginPage.js:
exports.get = function(req, res) {
res.render('login');
};
The checkAuth.js:
module.exports = function (req, res, next) {
if(!req.session.user) {
res.redirect('/login');
}
next();
}
Any help on this will be greatly appreciated.
Thanks
If you aren't authenticated, you'll redirect the user and then try to render the index page. This causes the http headers to be sent twice, hence the error "Can't set headers after they are sent".
In checkAuth.js try:
module.exports = function (req, res, next) {
if(!req.session.user) {
res.redirect('/login');
} else {
next();
}
}
Currenty I am trying to add an error & notice function to my expressjs app. I thought that by calling
app.use(function (req, res, next) {
res.notice = function (msg) {
res.send([Notice] ' + msg);
}
});
the notice function would be attached to all res objects present in my application, enabling me to use it as follows:
app.get('something', function (req, res) {
res.notice('Test');
});
However, the example above does not work. Is there a way to accomplish what I'm trying to do?
You need to call next after adding notice method to res, and you need to add the middleware before routes definition.
var express = require('express');
var app = express();
app.use(function (req, res, next) {
res.notice = function (msg) {
res.send('[Notice] ' + msg);
};
next();
});
app.use(app.router);
app.get('/', function (req, res) {
res.notice('Test');
});
app.listen(3000);
Im trying to use the username as route in expressjs, to view their profile.
app.get('/:username', function (req, res, next) {
users.get_user(req.params.username, function (err, results) {
if(results[0]) {
res.render('/profile', {
title: 'Profile',
userinfo: results[0]
});
} else {
next();
}
});
});
users.get_user is a function wich gets the user from the db. If it doesn't find a user it goes on to the next route. I also have a lot of other pages like /start, /forum etc. Is this an insufficient way of doing this, because theres a call to the db each time it passes through the /:username route. My question is, is there a better more sufficient way?
Try defining the more specific routes (e.g. /start, /forum) before the /:username route in your application. Express matches routes in the order that you define them.
E.g. Do this:
app.get('/start', function(req, res, next) {...});
app.get('/forum', function(req, res, next) {...});
app.get('/:username', function(req, res, next) {...});
Not
app.get('/:username', function(req, res, next) {...});
app.get('/start', function(req, res, next) {...});
app.get('/forum', function(req, res, next) {...});
This way, if the user goes to /start, it won't hit the /:username route and cause a database hit.