WebDev: jQuery, JSON, IE and Caching

I’m almost ready to update the production version of UVFood.com. I’ve been testing against Firefox during development, but I can’t possibly deploy the update without testing against other browsers. Safari turned up no surprises, and Opera has turned up a weird little problem that doesn’t make any sense.

But of course it was Internet Explorer that had the biggest issues.

Bookmarking is done via Ajax. When you bookmark a listing the icon changes from a heart with a plus sign to a heart with a minus sign, the count of the number of times the the listing was bookmarked is updated and a message is displayed that confirms the item was bookmarked. This works fine with Safari, Firefox and Opera. Internet Explorer, however, exhibits some truly erratic behavior. When you bookmark a listing in IE everything you expect happens. But when you click again to remove it from the bookmarks – everything that happened the last time happened again.

Entering a review worked, though. But clicking stars to rate a listing had a similar problem.

The problem was that jQuery on IE was caching the JSON results, something it wasn’t doing on Safari or Firefox.

The first thing I tried was to make sure that my server returned a header in the response to tell the client not to cache the results. It’s a simple header line:

Cache-Control: no-cache

Unfortunately this didn’t change anything. It’s still good practice to make sure that your server emits the correct cache control headers, though.

Then I remembered a discussion of jQuery and GET vs. POST methods. GET is meant to be idempotent, no ill effects if it’s repeated (a request to move to position 8 is idempotent; a request to move to the next position is not). And it may be okay to store the results of a GET. POST is meant to be used for other requests.

Unfortunately, the convenience function that jQuery offers for dealing with jSON Ajax requests is getJSON(), which uses a GET request. It’s easy to write a postJSON() convenience function, however. Just add this to your jQuery initialization code:

$.postJSON = function(url, data, callback) { $.post(url, data, callback, "json");

Changing my code to use postJSON() instead of getJSON() solved the problem.

Offline jQuery Documentation for MacOS X

I’m rewriting UVFood to use jQuery instead of Prototype. I’m liking jQuery quite a bit and my code’s looking much better (and tighter).

I don’t always have reliable online access when I’m coding – in particular, I was on a bus today for a couple of hours and didn’t always have Internet access. There are a couple of dashboard widgets for MacOS X which I found that helped out on the jQuery documentation front.

First, there’s http://code.google.com/p/jquery-reference/. This widget is designed for browsing… click around in it, but don’t expect to search it.

Then there’s also http://blog.medallia.com/2007/05/jquery_reference_widget.html. This widget is designed for searching – if you know what you’re looking for, you can find it quickly.

They’re both useful in different ways, and I used them both this afternoon.

LJ Crossposting

I have a bunch of half-written things that I haven’t finished because I haven’t been happy with the state of cross-posting between this blog and Livejournal and I haven’t really had the time to deal with fixing it.

I’m cross-posting to make it easier for friends on LJ to read my blog entries. I find that using LJ to follow friends is a great feature; it’s what keeps me coming back to LJ.

It looks like I have it working now. I currently have it set up to cross-post everything. I’ll be writing a lot more technical articles in the near term, with some non-technical stuff mixed in. If you’d rather that I didn’t cross-post, or didn’t cross-post everything, let me know and I’ll see what I can figure out about limiting it.

I have cross-posting set up to require that comments be left here instead of on LJ. If you want to comment, you can use OpenID to login – instead of creating an account, just use the OpenID option on the account creation page. You can then authenticate yourself with Livejournal and not have another account to keep track of.

Continue reading

Brian Eno Is Alive and Well in My iPhone

Bloom screenshot

The most entertaining iPhone app I’ve seen so far comes from Brian Eno and Peter Chilvers and is called “Bloom”.

Given the current events in the US (or global) economy, “Bloom” rescues me from continually listening to only chill-out music and Radiohead’s most apocalyptic songs.

Instead, “Bloom” allows me to anesthetize (or lobotomize) myself with a mini-Eno, embedded in my iPhone, happy to produce ambient music on demand or from my cue.

The screen is a fuzzy pastel color, varying with your mood (“Bergamot”, “Vetiver”, “Ylang”, “Banzoin” and others). You can choose to have it create music for you, or to give it some cues by tapping various parts of the screen. Tap out a few notes and it will play them back, looping them into a piece of ambient fuzz that could just as well be a song from "Music for Airports". You can freeze the melody from evolving if you like it, but there are no provisions for saving, recording or sharing it, which is just as well.

I was so enthralled with it after buying it that I lost track of time and was late to an appointment.

“Bloom” costs $3.99 and you can buy it through the iTunes Store. Here are screenshots of the preferences:

"Bloom" About Page

"Bloom" preferences

"Bloom" preferences

Showing a Column as a UNIX Timestamp in MySQL

I often need to store a timestamp in the UVFood database. There are lots of things I need timestamps for – recording the time that a user account was made or a modification was made, for instance.

While MySQL has quite an assortment of date and time formats which it supports, I usually find it most convenient to store timestamps as an INT and just put the UNIX seconds since the epoch value in there. I don’t need to do funky searches on the timestamps, I just need to do simple comparisons.

A drawback is that sometimes when I’m working with the database by hand it’s annoying to see the timestamps as big numbers – sometimes it would be very helpful to see them as dates and times.

Fortunately there’s a MySQL function that helps with this problem. The “FROM_UNIXTIME()” function will interpret a numeric column’s value as a UNIX seconds-from-the-epoch value and show it as a date and timestamp.

Using it I can easily do things like:


SELECT URL, FROM_UNIXTIME(Timestamp) FROM AccessLog;

and see it as:


+---------------------------+--------------------------+
| URL | FROM_UNIXTIME(timestamp) |
+---------------------------+--------------------------+
| explore/users/94 | 2008-10-05 22:49:39 |
+---------------------------+--------------------------+

rather than


+---------------------------+------------+
| URL | timestamp |
+---------------------------+------------+
| explore/users/94 | 1223261379 |
+---------------------------+------------+

%d bloggers like this:
var _gaq = _gaq || []; var pluginUrl = '//www.google-analytics.com/plugins/ga/inpage_linkid.js'; _gaq.push(['_require', 'inpage_linkid', pluginUrl]); _gaq.push(['_setAccount', 'UA-239812-12']); _gaq.push(['_trackPageview']); (function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://' : 'http://') + 'stats.g.doubleclick.net/dc.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); })();