Thursday, September 23, 2010

Conditional (fab) HTML Apps

‹prev | My Chain | next›

Up tonight, I would like to get rid of the idle timeout alert() in my (fab) game. I have already done this once when I was playing with express. Now I would like to do the same on version 0.5 of fab.js.

First up, I update the good-bye function in the client to redirect (instead of alert()-ing) to the login page with an appropriate message:
    var goodbye = function() { 
window.location = window.location.protocol + '//' +
window.location.host +
window.location.pathname +
'?message=You have been logged out.' ;
};
player_list = new PlayerList(me, room, {onComplete: goodbye});
In the express.js version of the code, I had used flash/session to accomplish this. There is no flash in fab (yet), so query strings will have to suffice.

With that, I need to grab the message out of the query string and insert it into the HTML. Since I am using (fab) HTML apps to render the HTML, I need to make the message display a (fab) app as well:
  (route, /^\/board/)
( HTML )
( head )
( BODY )
( info )
( FORM, { id: "login", method: "get" } )
// form stuff
()
( DIV, { id: "room-container" } )()
() // BODY

() // HTML
()
Fortunately, I am getting pretty good at this:
function info(write) {
return write(function(write, head) {
Logger.info(inspect(head));
return write;
});
}
Well, maybe not too good. I know how to write a (fab) app that gets called with a response (write) stream. I also know that returning that response stream with a callback will allow any other upstream apps (e.g. the FORM and other HTML apps) to write to the response stream as well. Lastly, I know that the callback in this situation is called with the response stream, the request header (head) and the request body (which I do not need).

What I do not know (or at least do not remember off the top of my head) is where in the head the URL and query string are buried. To find out I access the /board resource with a query string of foo=bar and see what Logger.info tells me:
[INFO] { method: 'GET'
, headers:
{ host: 'localhost:4011'
, connection: 'keep-alive'
, accept: 'application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5'
, 'user-agent': 'Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.7 (KHTML, like Gecko) Chrome/7.0.517.8 Safari/534.7'
, 'accept-encoding': 'gzip,deflate,sdch'
, 'accept-language': 'en-US,en;q=0.8'
, 'accept-charset': 'ISO-8859-1,utf-8;q=0.7,*;q=0.3'
}
, url:
{ href: '//localhost:4011/board?foo=bar'
, slashes: true
, host: 'localhost:4011'
, port: '4011'
, hostname: 'localhost'
, search: '?foo=bar'
, query: 'foo=bar'
, pathname: ''
, capture: []
}
}
Ah, in the url.query property. I know how to extract query parameters. node.js provides a querystring parse function to accomplish this:
function info(write) {
return write(function(write, head) {
var q = require('querystring').parse(head.url.query);
if (q.message)
write('<div id="info">' + q.message + '</div>');

return write;
});
}
And it turns out, that is all I need. When the idle timeout is broadcast, the goodbye function is called in the client, which redirects to the login page with a message and I see:



Easy enough! I think I am finally getting the hang of the new version of fab.js.

Day #235

No comments:

Post a Comment