FlipClock Available on the Chrome Web Store

I just published my FlipClock webapp to the Chrome Web Store.

It was remarkably easy to package it up. I have to hand it to Google, they've made it pretty easy to publish a JavaScript based webapp to their store. The process basically entailed adding a manifest.json to the project and packaging the directory into a ZIP file. If you're interested, you can check out the source on Github or bitbucket.

In short, you should install it and enjoy watching the time flip away...

Cross-domain AJAX, Express.js and Access-Control-Allow-Origin

I have a tip for anyone working with node.js frameworks, in my case it's the Express framework, but this applies to any framework that binds to URL patterns.

I've been working out some JavaScript on jsFiddle that involves AJAX requests to an endpoint I have running on a node.js server external to jsFiddle. Part of this requires that the Access-Control-Allow-Origin header be setup to allow access from external domains. You can do this in Express by adding the header to your response object with:

res.header("Access-Control-Allow-Origin", "*");

I had a route that looked something like this:

app.get('/posts', function(req, res){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.send(
{ posts : ... }
);
});


But it wasn't working in Chrome, I kept seeing the error "XMLHttpRequest cannot load http://... Origin http://fiddle.jshell.net is not allowed by Access-Control-Allow-Origin." even though I was setting the correct header.

Turns out that there was a OPTIONS request being sent before the GET request that didn't match my route and it was failing with the previous error. Problem is, Chrome didn't show the request in the Inspector's Network tab so it took me a long time to figure out what was happening.

The fix is a pretty simple one; you need to make sure your route in Express matches the OPTIONS request as well as the GET request. The easiest way to do that is to bind with app.all(...) to match on all requests. So the updated and working code is:

app.all('/posts', function(req, res){
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.send(
{ posts : ... }
);
});


It's also important to note that I needed to set the Access-Control-Allow-Headers header to allow "X-Requested-With". Without it, it generated a similar error: "XMLHttpRequest cannot load http://... Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers."

Startup Weekend Boston and Developing PocketRoster

Last weekend, Startup Weekend Boston took over a whole floor of the Microsoft NERD Center in Cambridge and for 54 hours, entrepreneurship, development and lots of caffeine were the rule. This is my experience over the weekend and how the PocketRoster app was developed.

The weekend started on Friday evening with around 50 ideas presented in rapid fire succession, with 60 seconds being given to each idea. There were a lot of ideas, but after a round of discussion and voting on each idea only about half remained. Among them was the idea for an mobile organization directory app presented by Howie Hecht. That idea piqued my interest and I joined his team. Unfortunately, no one else shared my interest and we ended the evening with only two members on our team. After a quick meeting we decided to go ahead with the idea and got a basic plan for the app hashed out before leaving for the night.

Saturday started at 9am in the morning with and we spent the day working out the fundamentals of the application and strategies for making a profitable business out of it. From a development point of view, two days is a pretty short time for developing a working mobile site, but by paring down the required features to the bare minimum and by using a number of relatively new frameworks and technologies we were able to get a good looking and functional mobile app completed.

The first of the frameworks I used was Silex, a new PHP 5.3 micro-framework based on components from Symfony2, a popular php framework. The way Silex works is by binding closures (functions) to url paths like:

$app->get('/user/{username}', function($username) {
return "User profile for $username";
});


Combined with a powerful templating engine like twig that supports template inheritance, you can rapidly bind variations of a template to different url patterns. Using a base template with a standard page structure you can move all the common code for analytics, ads, etc... into it and you only have to write the page specific elements in each template. For storing data I ended up using Mongo for it's flexibility and because I could reuse components I've previously written for my foundry-core library.

For the front end I chose JQuery Mobile and was impressed by it's ease of use. It's pretty quick to get up and running with very little code required. They also have a decent amount of documentation on the basics which helped immensely when putting together the structure of the app but was lacking when it came to troubleshooting issues that popped up during development. My overall impression is definitely favorable, but I don't think it's quite good enough to replace native apps. There is a lot of loading time involved between pages that really slows down the experience. I think I could probably get around a lot of it by pre-loading templates and with some caching of content, but the effort required is probably better spent writing native apps. In it's current form it's a great tool for prototyping, but not yet a viable long term solution.

Unfortunately, we didn't win the contest on Sunday, that honor went to CaseReportal, a medical reporting/collaboration tool. But we do plan on pursuing our project since it has great applications and we were able to confirm the demand for such a product. If you want to learn more about it you can sign up for an account at http://pocketroster.me and try it out on your mobile device. If you think you'd like to use our product for your team or organization or if you have feedback for us you can contact us at feedback@pocketroster.me.