Bleh. I had planned on playing about with mustache.js in express, but then I remembered, I hate writing HTML. I blame Haml. Instead, I will stick with trying to play with sessions in express.
I do not really need sessions in my (fab) game, but I will try to use flash session messages when the player gets logged out after idling too long. First up, in the jade template, I redirect the player to the
/idle_timeout
resource when the backend signals that the player is no longer welcome in the game:| var goodbye = function() {I need to define that resource to set a flash message and then redirect back to the main player board:
| window.location = window.location.protocol + '//' + window.location.host + '/idle_timeout';
| };
app.get('/idle_timeout', function(req, res) {When I access this resource, however, I get a sad little stacktrace:
req.flash('info', 'You were logged out because you weren\'t doing anything.');
res.redirect('/board');
});
TypeError: Cannot read property 'flash' of undefinedHrm... That error is not coming from my (fab) game, it is coming from express. Looking at that method, it seems as though the session is not present:
at IncomingMessage.flash (/home/cstrom/.node_libraries/.npm/express/1.0.0rc2/package/lib/express/request.js:152:49)
at Object.<anonymous> (/home/cstrom/repos/my_fab_game/game.js:39:7)
at pass (/home/cstrom/.node_libraries/.npm/connect/0.2.4/package/lib/connect/middleware/router.js:65:27)
at Object.router [as handle] (/home/cstrom/.node_libraries/.npm/connect/0.2.4/package/lib/connect/middleware/router.js:80:10)
at next (/home/cstrom/.node_libraries/.npm/connect/0.2.4/package/lib/connect/index.js:264:23)
at /home/cstrom/.node_libraries/.npm/connect/0.2.4/package/lib/connect/middleware/staticProvider.js:87:21
at node.js:764:9
http.IncomingMessage.prototype.flash = function(type, msg){I start acking through the express code for session, when I come across an example app for express sessions. Just what I need. It suggests that I need to add two lines to the
var msgs = this.session.flash = this.session.flash || {};
// ....
};
createServer
call:// Create the Express serverI try adding just the
var app = express.createServer(
express.cookieDecoder(),
express.session()
);
express.session()
line, but get warnings about needing the cookieDecoder
. Sure enough, once I add that in, flash works. Well, at least it is not crashing.To get this working, I add an
#info
div to my jade template:#info= flash.infoBut I always see 'undefined' in that div. I think that I am populating it correctly as a local, template variable, but I inspect the flash just to be sure:
...
app.get('/board', function(req, res) {In the server output, I see:
puts(inspect(req.flash));
res.render('board', {locals: {flash: req.flash}});
});
[INFO] timeout foo!Ah!
[INFO] players.drop_player foo
[Function]
req.flash()
is a function, not an attribute. Easy enough:app.get('/board', function(req, res) {And now I see the flash message in the server output:
puts(inspect(req.flash()));
res.render('board', {locals: {flash: req.flash()}});
});
[INFO] timeout foo!Except, in the browser, I still see 'undefined' where the info message should be. Am I invoking the
[INFO] players.drop_player foo
{ info: [ 'You were logged out because you weren\'t doing anything.' ] }
render()
method wrong or is something else breaking? I will check the latter first. What is the value of the info attribute?app.get('/board', function(req, res) {Now, when my player times out:
puts(inspect(req.flash()));
var info = req.flash().info;
puts(inspect(info));
res.render('board', {locals: {flash: flash()}});
});
[INFO] players.update_player_status: fooAh, damn! I've got a Heisenberg thing going on here. Looking at the flash in the first place destroyed it. To get around this, I squirrel away the flash immediately:
[INFO] timeout foo!
[INFO] players.drop_player foo
{ info: [ 'You were logged out because you weren\'t doing anything.' ] }
undefined
app.get('/board', function(req, res) {Now, I get the info attribute that I have been expecting:
var flash = req.flash();
puts(inspect(flash));
var info = flash.info;
puts(inspect(info));
res.render('board', {locals: {flash: flash}});
});
[INFO] timeout foo!With that, I finally get the flash warning to show up on the page.
[INFO] players.drop_player foo
{ info: [ 'You were logged out because you weren\'t doing anything.' ] }
[ 'You were logged out because you weren\'t doing anything.' ]
One last thing I need to add is a jade conditional so that the
#info
div is not displayed unless flash.info
is present (it displays undefined
otherwise). The conditional:- if (flash.info)Simple enough.
#info= flash.info
Well there were certainly a few gotchas in there, at least for this beginner, but I finally got sessions working in express. Tomorrow I plan to head back to faye land to see if I can gracefully handle writes to blocked browsers.
Day #212
Thanks for the post, I just went through the exact same confusion and steps.
ReplyDelete