Name:
Location: United Kingdom

I am a software developer and consultant with more than a quarter of a century of technology change and challenges to draw experience from. While I maintain and exercise some skills from the dark ages of computing I also enjoy taming the new technologies as they turn up – always looking for ways to deliver truly effective software systems to my customers.

Monday, April 23, 2007

Humiliation is the name of the game

I remember reading a great book by David Lodge titled “Changing Places”. In this novel (written in a sequence of literary styles – I know that sounds dreadful but it is subtle and funny) an English academic who has swapped places with a US professor introduces a game to his US university English Department hosts one evening over dinner. The game is called “Humiliation” and the object is to name a book that you have not read but that your peers would consider it humiliating to admit that you had not read. The dilemma is a choice between losing the game or admitting to a failing in such an august company. In the novel, the desire to win at all costs brings a young US academic to the end of his career.

At the risk of my reputation, it is time to admit that I have only just tried using JSON. I have always been quite comfortable with XML and while acknowledging that JSON looked like an interesting alternative I could not see a compelling reason to use it. I always try to promote a rich user experience within my web applications and this can often mean using Ajax techniques. Sometimes, Ajax is not possible (some portals do not work well with this technology) and sometimes it is not advisable for other reasons. One technique I have evolved is what I call “Fake Ajax”. This involves passing lots of support data to the client in hidden page fields ready to be loaded into JavaScript objects as and when required. The same technique can be used to pass data back again if it has been manipulated by the user. It looks slick, improves the user experience and all at a minor up front cost of adding some bytes to the size of the initial page load. An obvious candidate for JSON you would think. Certainly I was persuaded to give it a go when I needed to deliver what was, in effect, a two dimensional array of Booleans to a web page – just in case the user needed to review or edit the data. XML seemed a rather heavy approach to a few “bits” of data so it was time to try JSON.

If you need an alternate opinion on the joys of JSON then you should visit Dustin Diaz’s “JSON for the masses”. He slightly confuses the concept of ‘name spaces’ with ‘scope’ but it is a fun read Part of the problem with JSON is that applying it is so easy all examples look too simple and banal – leaving the reader with the idea that somehow JSON is more complex and difficult to understand. Thus I am going to show you the code for managing a complex block of data – just to demonstrate how simple it all is. The “fiddley” bit in building a Jason string is in ensuring that your data is in name/value pairs as it seems easy to lose track – particularly when you start creating arrays of objects. The values themselves can be strings, numbers, Booleans, arrays, null or another object described in the same format. As this is JavaScript you can also supply function definitions as values as well.

A simple, yet complete, introduction to JSON

My data scenario is that I have some related events that occur during a week but that may or may not coincide in a given day. I have to provide access to the most recent week’s record so that the user can keep things up to date. In addition, the user might want to review (and possibly) edit the previous n weeks of similar records. In my JSON object I have separated the current week from the historical data but it might be proper in another application to combine the two variations into a single list of values. My data is simple – just a list of Boolean values indicating if a given event occurred on a given day.

But let’s take it one step at a time.

I can define a relatively simple JavaScript object as a JSON string like this:

{‘visitor’: {
‘name’: ‘Emily Smith’,
‘phone’: ‘0123 56789’,
‘email’: ‘emily@hercompany.com’
}
}


(the tabs, spaces and line feeds are to aid readability and are not needed)

What we have here is an initial name/object pair – the name being ‘visitor’, followed by a colon and then the related object wrapped up in its own pair of braces. This object , in turn, contains three name/data pairs. Each name and data element are separated by a colon and each pair is separated by a comma.

To turn this JSON string into a JavaScript object – all we need to do is use the JavaScript eval() function. The string might be passed to the client side web browser in an element of the page HTML or in response to an Ajax request.

The JavaScript code line would look something like:

var vData = eval(‘(‘ + request.responseText + ‘)’);

Assuming that your JSON string is stored in the request.responseText object then subsequent code could address the data elements of the newly created object (vData) using something like the code below:

var name = vData.visitor.name;
or
var email = vData.visitor.email;

which has the advantage of being clear straightforward and hopefully self documenting.

So let’s introduce an array to our JSON object.

{‘visitor’: {
‘name’: ‘Emily Smith’,
‘phone’: ‘0123 56789’,
‘email’: ‘emily@hercompany.com’,
‘payments’: [123.45, 234.56, 345.67]
}
}


with the new data being available at the client with code something like:

alert(‘The second payment was ’ + vData.visitor.payments[1]);

showing that an array of numbers is just as accessible as our original object strings.

Now let’s try the object from my project:

{
'thisweek': {'eventa': [true,true,true,false,false,false,true],
'eventb':[true,false,true,false,false,false,false]},
'history': [
{'weekid': 8,
'weekdate': '11-03-2007',
'eventa': [false,false,true,true,false,true,true],
'eventb': [true,false,true,true,false,true,true]
},
{'weekid': 7,
'weekdate': '04-03-2007',
'eventa': [false,false,true,true,false,true,false],
'eventb': [true,false,true,true,true,true,true]
}
and so on…
]
}


So what does this consist of? At the highest level we have two name/value pairs (the names are ‘thisweek’ and ‘history’). The first value is an object and the second is an array – which contains more objects. Each object in the array is separated by a comma and contains 4 name/value pairs – with the second two such pairs being themselves arrays (of Booleans). Using integer values would have made the string shorter but the total string length here was not affecting performance.

I don’t think it can get any harder than this and at the client end there is almost nothing to do. Many prefer JSON to XML because it is more succinct, simple to address from client side JavaScript and yet the meaning is still clearly human sensible.

What’s the downside with JSON? Well I think that debugging an object string being created by code from server side data is more difficult than debugging the equivalent XML. I find it pretty easy to spot malformed XML tags and once any of those are tidied up it is simple to load an XML string into your web browser and inspect the structure. Long JSON strings are a mass of brackets, quote marks and commas that can take some sorting out. I suspect that a tool could be written to do this as a debugging aid but a casual run around Google did not turn up anything that went far enough. If the eval() function returns and error, it tends to be rather enigmatic.

For immediate use within an ASP.NET application it makes sense for me to write a new class to accept and store name/value pairs with a method that can serialise the stored content as a JSON string. I will publish my prototype shortly.

Conclusions from my first foray? Well I am going to make strategic use of JSON into the future as it simplifies the storage of data at the client end of the process. I will look for opportunities for JSON where that simplification can improve performance of simplify the code.

JSON has one key advantage in true Ajax enabled applications. It can be used to download data from a third party server. The XMLHttpRequest object is restricted to accessing the domain that served up the JavaScript file currently being executed. The Script element does not share this security restriction and thus you can request JSON format responses from alternate domains and from web services. Indeed, if you provide a web service then you should consider offering JSON as one of your response formats as this allows the consumption of your web service asynchronously from a client rather than just from your user’s servers.

You might well want to visit JSON.Org to pick up a copy of the JSON Parser (for use when accepting JSON from less trusted sources) and the JSON “Stringifier”. You might also want to download a version of Douglas Crockford’s JavaScript “minifier” to compress your JavaScript files if you do not already have one available on your development machine. It was Douglas Crockford, that guru of JavaScript, who created the JSON meme in the first place.

0 Comments:

Post a Comment

Links to this post:

Create a Link

<< Home