I have a page with a route GET /team
which is loading a list of teams, and DEL /team
which is deleting a team from /team/:key
. So you navigate to a team's profile page and delete them from there, on deletion it should redirect you to the /team
page. I have put logs into the console and it is successfully deleting the team
and wierdly, it says it is loading /team
but the browser does not load this. I have put my code below, any ideas?
Routes:
app.get('/team'/*, lim("Must be logged in to see teams")*/, getAllTeams, function(req, res){
util.log('Serving request for url [GET] ' + req.route.path);
// Pass it the list of all Teams
res.render('team', {'teamsList' : req.teamsList} );
});
app.get('/team/:key', function(req, res) {
util.log('Serving request for url [GET] ' + req.route.path);
Team.findByKey(req.params.key, function(err, teamData){
if(!err && teamData){
teamData = teamData;
res.render('teamDetails', { 'teamData' : teamData } );
} else {
util.log('Error in fetching Team by key : ' + req.params.key);
res.json({
'retStatus' : 'failure',
'msg' : 'Error in fetching Team by key ' + req.params.key
});
}
});
});
/**
* DEL /team/:key
* Delete Team by key
*/
app.del('/team/:key', getAllTeams, function(req, res) {
util.log('Serving request for url [DEL] ' + req.route.path);
Team.remove({key : req.params.key}, function(err){
var message = '';
var retStatus = '';
if (!err) {
util.log('Successfully deleting Team with key: ' + req.params.key);
message = 'Successfully deleting Team with key: ' + req.params.key;
retStatus = 'Success';
res.redirect('/team');
} else {
util.log('Error deleting Team with key: ' + req.params.key + 'Error: ' + util.inspect(err));
res.json({
'retStatus' : 'failure',
'msg' : 'Error in fetching Team with key ' + req.params.key
});
}
});
});
JavaScript + HTML template:
button#teamDelete.btn.btn-danger.btn-mini(type="submit", value="Delete Team") Delete
script(type='text/javascript')
$('#teamDelete').live('click',function(){
var teamId = #{teamData.key};
$.post('/team/' + teamId, { _method : 'delete' }, function(response) {
console.log(response);
if(response.retStatus === 'Success') {
if('/team' && '/team' !== "") {
window.location = '/team';
}
}
});
});
console logs:
10 Mar 11:52:01 - Serving request for url [GET] /team
10 Mar 11:52:02 - Serving request for url [GET] /team/:key
10 Mar 11:52:03 - Serving request for url [DEL] /team/:key
10 Mar 11:52:03 - Successfully deleting Team with key: 1362855941128
10 Mar 11:52:03 - Serving request for url [GET] /team
getAllTeams:
var getAllTeams = function(req, res, next){
Team.getAll(function(err, teamsList){
if(!err && teamsList){
req.teamsList = teamsList;
return next();
}
});
};
Team.getAll (Team schema)
Team.statics.getAll = function(cb){
var query = this.find({});
query.sort({key : -1});
return query.exec(cb);
};
I have a page with a route GET /team
which is loading a list of teams, and DEL /team
which is deleting a team from /team/:key
. So you navigate to a team's profile page and delete them from there, on deletion it should redirect you to the /team
page. I have put logs into the console and it is successfully deleting the team
and wierdly, it says it is loading /team
but the browser does not load this. I have put my code below, any ideas?
Routes:
app.get('/team'/*, lim("Must be logged in to see teams")*/, getAllTeams, function(req, res){
util.log('Serving request for url [GET] ' + req.route.path);
// Pass it the list of all Teams
res.render('team', {'teamsList' : req.teamsList} );
});
app.get('/team/:key', function(req, res) {
util.log('Serving request for url [GET] ' + req.route.path);
Team.findByKey(req.params.key, function(err, teamData){
if(!err && teamData){
teamData = teamData;
res.render('teamDetails', { 'teamData' : teamData } );
} else {
util.log('Error in fetching Team by key : ' + req.params.key);
res.json({
'retStatus' : 'failure',
'msg' : 'Error in fetching Team by key ' + req.params.key
});
}
});
});
/**
* DEL /team/:key
* Delete Team by key
*/
app.del('/team/:key', getAllTeams, function(req, res) {
util.log('Serving request for url [DEL] ' + req.route.path);
Team.remove({key : req.params.key}, function(err){
var message = '';
var retStatus = '';
if (!err) {
util.log('Successfully deleting Team with key: ' + req.params.key);
message = 'Successfully deleting Team with key: ' + req.params.key;
retStatus = 'Success';
res.redirect('/team');
} else {
util.log('Error deleting Team with key: ' + req.params.key + 'Error: ' + util.inspect(err));
res.json({
'retStatus' : 'failure',
'msg' : 'Error in fetching Team with key ' + req.params.key
});
}
});
});
JavaScript + HTML template:
button#teamDelete.btn.btn-danger.btn-mini(type="submit", value="Delete Team") Delete
script(type='text/javascript')
$('#teamDelete').live('click',function(){
var teamId = #{teamData.key};
$.post('/team/' + teamId, { _method : 'delete' }, function(response) {
console.log(response);
if(response.retStatus === 'Success') {
if('/team' && '/team' !== "") {
window.location = '/team';
}
}
});
});
console logs:
10 Mar 11:52:01 - Serving request for url [GET] /team
10 Mar 11:52:02 - Serving request for url [GET] /team/:key
10 Mar 11:52:03 - Serving request for url [DEL] /team/:key
10 Mar 11:52:03 - Successfully deleting Team with key: 1362855941128
10 Mar 11:52:03 - Serving request for url [GET] /team
getAllTeams:
var getAllTeams = function(req, res, next){
Team.getAll(function(err, teamsList){
if(!err && teamsList){
req.teamsList = teamsList;
return next();
}
});
};
Team.getAll (Team schema)
Team.statics.getAll = function(cb){
var query = this.find({});
query.sort({key : -1});
return query.exec(cb);
};
Share
Improve this question
edited Mar 10, 2013 at 15:17
germainelol
asked Mar 10, 2013 at 11:56
germainelolgermainelol
3,34115 gold badges48 silver badges83 bronze badges
8
- The /team GET route is expecting a parameter req.teamsList for rendering the page. Is it being made available in the redirect? – patalmypal Commented Mar 10, 2013 at 12:11
-
@almypal If I add in
{'teamsList' : req.teamsList}
to the redirect as I do when rendering the/team
page, and add ingetAllTeams
, nothing is shown in the console, and nothing is loaded still. – germainelol Commented Mar 10, 2013 at 12:27 - How do you add that to the redirect? – patalmypal Commented Mar 10, 2013 at 12:39
-
@almypal I tried adding
res.render('team', {'teamsList' : req.teamsList} );
but nothing loaded, I don't think it works with theres.render
but it doesn't work with just a simple redirect either because it is expecting a teamsList as you said, any idea how to fix the problem? – germainelol Commented Mar 10, 2013 at 12:45 - Is the /team GET route working standalone... if yes, how are the parameters being sent with the request... – patalmypal Commented Mar 10, 2013 at 12:57
2 Answers
Reset to default 2Your request is POST ($.post) and you route is app.del, so it never gets to res.redirect inside app.del route.
Why don't you use app.post?
Updated:
Assuming $.post sends HTTP DEL request here what is happening: server sends 302 response with no data but browser never sends another request to GET route as server instructs it (or does jQuery handle redirects too? Not sure). res.redirect() is actual HTTP response not some internal server-side instruction to re-route the request to another route like you can do in ASP.NET (and which is wrong actually)... Route is designed to receive request, reply with the response and forget about it. You need to separate routes from actual functions processing them, then you will be able to call that function instead of sending redirect.
Code suggestions
In app.del('/team/:key' ...
...
retStatus = 'Success';
// res.redirect('/team');
res.send({
retStatus : retStatus,
redirectTo: '/team',
msg : 'Just go there please' // this should help
});
...
Client-side in $.post('/team/' ...
...
$.post('/team/' + teamId, { _method : 'delete' }, function(response) {
console.log(response);
if(response.retStatus === 'Success') {
// not sure what did you mean by ('/team' && '/team' !== "")
// if('/team' && '/team' !== "") {
if (response.redirectTo && response.msg == 'Just go there please') {
window.location = response.redirectTo;
}
}
});
...
Not sure it will work though because I don't understand what your getAllTeams
does and why you store teamList
in req. If you want to store in session, than assuming the middleware is correctly configured you need to use req.session. If you need to store it only within request and your getAllTeams prepares this list of teams it is better to store in res.locals (like res.locals.teamList).
And make sure your getAllTeams calls next. So basically your getAllTeams should look like this:
function getAllTeams (req, res, next) {
res.locals.teamList = [/* whatever */];
next();
}
And then you can use res.locals.teamList in your route handler instead of req.teamList.
res.render('team', {teamsList : res.locals.teamsList} );
And 'team' template also can have a problem...
Express advice :)
Also the way you use Express makes it very difficult to extend/manage application. I don't remember where exactly, but somewhere in docs they write that Express is supposed to be used as the foundation for your application framework, not as a plete framework like most PHP frameworks are. It gives you a lot of power and flexibility, but also makes it necessary to think about your application architecture well in advance.
The most powerful feature of express is that you can have any route handled by many route-specific handlers/middlewares passing control to each other via next(). I have a static table that defines which handlers are used on each route allowing to see the whole application with 30 or so routes on one page. And this table is used to assemble the routing dynamically when the application starts. It leads to a lot of flexibility, manageability (I can move/copy-paste handlers from route to route - each handler is represented as a single word) and code re-use. I also use the same hash of routes definition in the client for client-side routing.
For a quick workaround, just add the redirect url to the response and on the client side do:
if (redirectUrl && redirectUrl !== "")
window.location = redirectUrl;