JQuery Mobile: a cautionary tale

I’m really a server-side fellow, at home with code that can be unit tested and where the only user is a computer. I suspect like most developers I find computers more predictable than people…

I’ve just finished a quick proof-of-concept for a nice bunch of people who wanted an API for their Web site. We needed a proof-of-concept for the proof-of-concept so we thought “well, what about a mobile Web site that calls the API?”

Well, it turned out that Microsoft’s most awesome WCF Web API made the first cut of the API a matter of a couple of day’s work. I guess I had should have rubbed my chin and had a sharp intake of breath and said to my colleagues “Oh, this’ll take ages” before ‘working at home’ on a beach somewhere pleasant. But I’m not professional enough yet too honest to do that.

So I ended up throwing together a little HTML5 Web site that used a little bit of JQuery Ajax magic to get some data from the API and sling it on to a page. I managed to get the Web API to play nicely with OAuth 2 authentication through Azure ACS from JavaScript (a blog post coming on that real-soon-now). My JavaScript application would request an access token through ACS which was then validated by my API.

Job done? Almost, just need a bit of styling and we’re there.

Or so I thought.

Naively, I was planning on pasting a bit of JQuery Mobile goodness on top of the Web site to make the buttons look pretty and the listboxes format appropriately. These things aren’t too hard with regular JQuery UI, after all; and given that the whole premise of the Semantic Web is that we shouldn’t have to worry about UI concerns in our markup, all should be well.

Whoops.

It turns out that to do the fancy page-transition malarkey, JQuery Mobile processes <a href=""> tags all by itself. You need to define a bit of your page that will transition, then the JavaScript cleverness loads the new content, slides it in place, then unloads your old content.

As far as the browser is concerned you’ve not actually changed URLs, it just looks that way. Which is fine… unless you need to handle pages which include querystrings.

Like I say, I’m really a server-side guy. I’m quite happy with RESTful addressing schemes where my WCF (or, indeed, MVC) app can interpret a nice long URI and figure out what resource needs to be processed.

The OAuth 2 libraries that Microsoft make available assume, reasonably, that these nice long URIs belong to the service, and that to pass around OAuth 2 tokens and what-have-you they can use querystrings.

So my rough plan of action was to check in JavaScript if my current access token had expired. I’d then do the usual OAuth redirect if it had, which should end me back on my page with a fresh token in the querystring.

Except JQuery Mobile always stripped off the querystring. Could I get it back? No – and this seems to be an intrinsic limitation of the library at the moment.

I worked around that in the short term by using a tiny ASP.NET site to directly squirt the access token into my pages. That wasn’t ever going to be a long-term solution, but worse was to come.

I was keen on making sure that the site would actually work on a real mobile device. Not having an iPhone to hand, and not having a laptop that supports the Windows Mobile SDK, I fired up an Android emulator.

Besides being incredibly slow, unsurprisingly the emulator didn’t really play properly on Windows. Configuring an Ubuntu virtual machine for the emulator helped a fair bit and seemed much more natural; it seems most Android developers work this way.

I managed to get my application running – but no data appeared. Something, somewhere, was causing an undefined “error” to occur deep in the bowels of JQuery during the AJAX call. Stripping out JQuery Mobile… everything worked.

So it’s just as well I didn’t go to the beach: doing this in pure JavaScript on the client was clearly going to be really hard to pull off. I gave up.

Two weeks later I had a full ASP.NET MVC site running that did all the OAuth and data retrieval server-side instead of client-side — and the application ran very nicely on Android and on the iPhone. But, I can’t package that up as an app. and submit it to an app store, and there’s still some dodgy code that works around the querystring issue.

So some morals, and things to bear in mind:

  • Even today, UI frameworks can invalidate assumptions followed by other bits of the code.
  • Do a quick trial of everything before you commit to a technology. If I’d found that cross-domain data access with Ajax was never going to work easily on Android I would probably not have gone further with the 100% JavaScript solution. Better would have been to validate all of the technology end-to-end.
  • Don’t cut your fingers on the bleeding edge. While up-to-the-minute latest-and-greatest technologies like JQuery Mobile may seem awesome at first glance there’s a reason for most systems to have a version 2. And version 3.