Christian Heilmann

You are currently browsing the Christian Heilmann blog archives for April, 2008.

Archive for April, 2008

Opera, REST APIs, Module Patterns and generated script nodes

Friday, April 11th, 2008

I just came across an annoying thing in Opera. I love using the Module Pattern for designing my JavaScripts and I love generating script nodes on the fly for REST APIs that give me back JSON. The following example using the twitter API works swimmingly on Firefox and Safari (have to check IE later, but I’d be surprised if it didn’t):



However, if you test this in Opera you get an error:


JavaScript – file://localhost/Applications/MAMP/htdocs/operacallbackfail.html
Inline script thread
Error:
name: ReferenceError
message: Statement on line 1: Reference to undefined variable: twitterbadge
Backtrace:
Line 1 of linked script http://twitter.com/statuses/user_timeline/codepo8.json?callback=twitterbadge.show&count=10
twitterbadge.show([{user : {screen_name : “codepo8”,...08”}]);

It seems like the newly generated script node calls the method of the module before the module has been created. In other words, newly generated script nodes halt the execution of the code that generated them. The following example works across browsers, including Opera:



Not too daunting a fix, but it feels wrong to have to have an extra method and another line calling it.

Try it out for yourself: Opera bug with dynamic script nodes and module pattern

Adobe onAir show in London

Thursday, April 10th, 2008

I almost didn’t hear about Adobe’s on Air conference until it was upon us and the list of attendees was full. Luckily I got hold of one of the organizers and got a ticket that way (thanks Mike !).

I have to admit that I was dreading the whole thing to be a terrible marketing-driven show and tell of out-of-the-box solutions that solve every problem web development throws at you. This was my experience with a lot of large product company shows in the past – I was proven wrong.

The onAir tour was a great experience, both in terms of organization and content. For a whole day (doors opening at 9.15am and the event closing at 6pm) several speakers told us all about Air – from low level command line building via using different IDEs all the way to deployment, automated update and security of your applications.

The schedule was very tight with a few breaks in between and a larger lunch break. There was no feeling of boredom ever as all speakers kept their presentations snappy and hands-on. If you got in a lull, the rock-steady wireless could keep you busy (although I realized that live-twittering what is going on angers folk though).

People already versed in the “Flash/Flex scene” that came to the conference said that for them a lot was not news, but I think the idea of the onAir tour was not to preach to the Flash crowd but to expand the developer community for the product. Talking to several “Adobe virgins” I got the impression they met their goal. Sam Clark for example told me he came with very low expectations but very strongly considers getting into Air development now.

Of course all of this is post-show enthusiasm, but there are a lot of things Air does that really makes it interesting for web developers:

  • you can use the technologies you are already using (HTML/CSS/JS)
  • you don’t have to worry about cross-browser and cross-platform incompatibilities (you work with WebKit, which also gives you alpha transparency, rounded corners and all the other CSS goodies we so crave to have cross-browser)
  • as a JavaScript developer you have reach you never had before – you can access the file system, create and access SQLite Databases or access 10MB of encrypted storage for your application (I remember messing around with .hta and COM objects to do this in JS once, not fun)
  • You have full access to the native windows and menus of the operating system, thus being able to write applications that look and feel exactly like any other the user is already familiar with.
  • The security model is much more sophisticated than what we have to deal with in JavaScript and browsers. That said, the option to be able to re-assign file associations for your application does sound potentially dangerous.

Of course not all is rosy about Air and the only presentation that showed the issues when implementing it on a large scale was the one by the BBC.

  • Air applications need to be installed, which is something that does spook out users paranoid about viruses. Ironically this is the only way to keep them secure – but it is a hurdle. The web installer badges are a nice way to ease this process.
  • The accessibility support is bad, this needs to get fixed, starting with proper keyboard support
  • Air applications seem to take up a lot of RAM when they run for a long time. According to Jonathan Snook this is largely caused by the library that creates growl windows and once this is fixed we’ll have less problems.
  • The installer is only available in English and needs to be i18n ready.

It is very interesting to see how all the web technologies seem to merge sooner or later with the common denominator being JavaScript. Seeing what Flash developers do with almost the same language I’ve used for years but unhindered by browser restrictions is pretty interesting and looks like a good challenge to marry the best practice quality ideas we found in the hostile browser world with this “let’s try if we can do it” attitude.

I also very much like the fact that Adobe promised to release all the presentation videos on their site after the road show and that they even provide an API to access all the media accumulated during the ride.

Of course there was schwag to go, in this case T-shirts and some goodies that were given out using raffle tickets. There was a tad of an embarrassing moment when I won twice, once with my own ticket and secondly with Steve Webster’s (who had to finish a project and couldn’t come). Hence I drew another winner and gave my prize away.

Good job, I am looking forward to the next event.

My wishlist for a great Ajax API

Tuesday, April 8th, 2008

Coming back from The Highland Fling it was interesting to see that people seem not to be quite convinced yet about the necessity of APIs and the large part they are playing in the next few years of web development. I guess this is partly based on experiences with APIs that aren’t properly explained to non-geeks and inconsistent or hard to use. There is just not much fun in trying to find information bit by bit if all you want to do is write some code (unless you have the old school hacker/cracker mind and didn’t consider spending hours looking at hexdumps trying to find a way to get endless lives in a games a waste of time).

During my interview with Paul Boag at I pointed out that designing a good API is as important as designing any other user interface – including your web page. Gareth Rushgrove agreed in his splendid talk How to be a first class web citizen. I also pointed out that there is a lack of clear and easy tutorials and articles on the matter, so I decided to have a go at it now.

Designing a great Ajax API

As an example I will use the recently released Google translation API, point out its good parts and list things I consider missing. I will not go into the part of actually writing the API but instead explain why I consider the missing parts important. This is not an attack towards Google, I just really liked working with this API and wanted to have it a bit easier to use, so no hard feelings, I really take off my hat that you offer an API like that!

Here are the points I consider important when we’re talking about Ajax APIs in JavaScript (Ajax implies that but you’d be surprised how often a REST API is advertised as Ajax):

  • Good documentation
  • Usage examples to copy + paste
  • Modularity
  • Link results to entries
  • Offer flexible input
  • Allow for custom object transportation
  • Cover usability basics

Documentation and presentation

Let’s start with a positive: the documentation of the Google Ajax Language API is great. You have all the information you need on one page including copy and paste examples. This allows you to work through the API online, read it offline and even print it out to read it on a crowded bus without having to take out your laptop.

Tip: If you are offering copy and paste examples – which by all means you should as this is what people do as a first step – make sure they work! I learnt the hard way in my book Beginning JavaScript with DOM Scripting and Ajax that there is nothing more dangerous than showcasing code snippets instead of full examples – people will copy and paste parts of a script, try to run it and either email you that your code is broken or – even worse – complain in book reviews on Amazon. If you offer copy and paste examples make sure all of them work independently.

Google offer explanations what the API is, what you can do with it, a list of all the parameters and what they mean. This is great for a first-glance user. For the hard-core audience they also offer a class reference.

Usage example

The first code example is quite good, you can copy and paste it and if your computer is connected to the Internet it will work – or it would, if the HTML got some fixes.

First of all it lacks a DOCTYPE, which is a bit annoying as it is a very important part of an HTML document. The more important bit is that the encoding is not set. The live example version has both – bit of a nuisance, as especially when we talk about different languages and using traditional Chinese as the example, the correct encoding is a must.

(Note: the irony, seems like wordpress doesn’t do this right for some reason …)







??????????



Tip: make sure you explain to people that your code examples need an internet connection and other dependencies (like requiring HTTP and thus having to run on a local server). JavaScript historically didn’t have any other dependency than a browser, this is changing lately and can be confusing, especially when you use Ajax behind the scenes like some Flash/Ajax APIs do!

Modularity is good!

The first bit that threw me off to a certain degree was the google.load("langage","1") line, but there is an immediate explanation what it means.

The first script include loads a generic Google Ajax API that has a load() method to add other, smaller APIs build on top of this one. In this case the line means you want to load the language API with the version number 1.

This appears clunky and you will get bad feedback for it (it seems there is nothing better the woo the masses to have a one script include solution) but is actually rather clever.

By modularizing the Ajax code in a base library changes to the core functionality will be easy and by asking the implementer to include the APIs he needs with a version number you can make it the choice of the implementer to upgrade instead of breaking older implementations or having to carry the weight of full backwards compatibility.

Yes, the perfect world scenario is that you’ll never have to change the functionality of your API - just add new features – but in the real world there are constant changes that will make it necessary for you to mess with the original API. There is no such thing as perfect code that is built for eternity. Using a loader function in the base API is also pretty clever, as it means that implementers don’t need to change URLs.

What goes in should come out.

This is where Google created a problem. Both the google.language.detect() and the google.language.translate() methods are quite cool insofar they offer you to send a string and define a callback method when the API returned a value. However, the returning object in both cases gives a result and a status code, but not what was entered. You get all kind of other information (described in the class documentation) but having the original entry would be very useful.

Why? Well the great thing about Ajax is that it is asynchronous, and that is also its weakness. It means that I can send lots of requests in the background in parallel and wait for the results. However, this does not mean that the requests also return in the right order!

This means that if you want to loop through an array of texts to translate, the following is an unsafe way of doing it:

var translations = [ ‘one’,’two’,’three’,’four’,’five’,’six’,’seven’,’eight’,’nine’,’ten’];
var gtl = google.language.translate;
for(var i=0,j=translations.length;i gtl(translations[i],’en’,’de’,function(result) {
if (!result.error) {
var container = document.getElementById(‘translation’);
container.innerHTML += result.translation;
}

});
}

Instead you need to wrap the incrementation of the array counter in a recursive function:

var translations = [ ‘one’,’two’,’three’,’four’,’five’,’six’,’seven’,’eight’,’nine’,’ten’];
var gtl = google.language.translate;
var i=0;
function doTranslation(){
var gtl = google.language.translate;
if(translations[i]){
gtl(translations[i], ‘en’, ‘de’, function(result) {
if (!result.error) {
var container = document.getElementById(‘translation’);
container.innerHTML += result.translation;
i++;
doTranslation();
}

});
}

}
doTranslation();

This is safer, but we lost the opportunity to have several connections running in parallel and thus getting results faster. If the result of the API call had the original text in it, things would be easier, as we could for example populate a result object and match the right request with the right result that way:

var translations = [ ‘one’,’two’,’three’,’four’,’five’,’six’,’seven’,’eight’,’nine’,’ten’];
var gtl = google.language.translate;
var results = {};
for(var i=0,j=translations.length;i gtl(translations[i],’en’,’de’,function(result) {
if (!result.error) {
results[result.input] = result.translation;
}

});
}

Even easier would be a transaction ID to pass in which could be the counter of the loop. Another option of course would be to allow more flexibility in the data that goes in.

Offering flexible input

Both the matching of the input text with the result and a transaction ID still would mean a lot of requests to the API, which is not really nice as it costs money and clobbers the server and the client alike. An easier option would be to not only allow a string as the text parameter but also an array of strings. The return then would also become an array and a lot of the overhead of calling the translation engine would be done on the server in a single call instead of lots and lots of API calls.

This is not hard to do and most JavaScript framework methods work that way, by checking the type of the first argument and branching accordingly. You can even go further and allow the implementers to send an own bespoke object as a third parameter.

Transporting a custom object allows implementers write a lot less code

The benefit of a custom object going out and in is that you can add more parameters to the API call that are only specific to the implementation. Most likely this could be a reference to a namespace to avoid having to repeat long method names or global variables. You could start by providing parameters that make sense to any Ajax call in terms of usability.

Thinking Ajax usability

The main thing any Ajax call should offer a user is a timeout. There is nothing more disappointing than getting the promise of a brave new Ajax world with much more interactive interfaces and then getting stuck looking at spinning wheels or worse hitting a link and getting nothing. Right now the language API has nothing like this, and you’d have to roll a solution by hand. You’d also have to check the error status code to see if the data could not be retrieved and call a failure case of the connection that way.

A nice API would offer me these options, most likely all rolled in one parameters object.

My dream translation API

Taking all these into consideration it would be perfect to get the API to offer these options:

google.language.translate(input,parameters);

The parameters would be:


input // string or array
parameters // object with the following properties
sourceLanguage:string,
targetLanguage:string,
transactionId:string,
customparameters:object, // to transport
timeout:integer, // (in milliseconds)
failure:function(result,params), // (method to call when there is a timeout or an error)
success:function(result,params), // (method to call when all is fine)

The returned data from the API should have both the result and the parameters provided. This would make the life of implementers dead easy.

Summary

In summary, here’s what I expect from a great Ajax API:

  • Have a good documentation with immediate copy and paste examples backed up by a full class documentation
  • Build your APIs modular and allow the implementer to choose the version they want to have
  • Provide a hook to link the result of the API methods to the initial data entered. The easiest way is to repeat this data, more sophisticated is to allow for a connection ID.
  • Allow for multiple values to be sent through, it’ll save you API calls and the implementer hacking around the problem of unreliable order of returns.
  • Allow implementers to add an own object to send and get back to allow for namespacing and other data state retention.
  • Allow for a timeout, connections are not to be trusted.

This is a work in progress

I hope you found something here to agree with and if you know things to add, just drop a comment.

Yay, Yahoo UK finally looks for some junior developers!

Friday, April 4th, 2008

Ever since I started working for Yahoo in England I’ve been lucky enough to recommend a lot of developers I wanted to work with for ages and get them hired to work here. One thing that annoyed me a bit is that we only took on very skilled and experienced developers. I consider a good team not to be people that are very very good but also a team where new developers can come in and grow with the rest of the team, learn from the others working on real projects and thus having a steady, maintainable, healthy flow of talent coming in replacing those that leave or want to move into other positions.

Now we get the chance to do so. If you are a web developer and you want to work with the very skilled people here in the west-end of London, check out the official job description below and send me a CV. Just comment here and I’ll mail you directly or send a mail to onlinetoolsorg@gmail.com.

Here’s the official job description:

Yahoo! Junior Web Developer – Job Description

As the world’s number one Internet brand Yahoo! delivers news, entertainment, information and fun to over a half billion people every day. Our European web development team, based in London, is seeking standards-savvy front-end developers to work on Europe’s busiest sites.
You should be able to provide examples of your work showing use of progressive enhancement techniques (e.g. unobtrusive scripting), and clear separation of structure, presentation and behaviour layers.

Required Skills

  • Hand-coded (X)HTML, CSS, and JavaScript
  • Solid knowledge of standards-based, accessible, cross-browser web development
  • PHP programming skills
  • User-level experience with BSD/Linux
  • Experience using version control systems such as CVS & Subversion

Desirable Skills

  • Client- and server?side performance optimisation techniques
  • Search engine optimisation
  • Experience in developing web applications with rich client interfaces using AJAX, drag and drop, and other DOM Scripting techniques.
  • Experience with JavaScript libraries, especially the YUI
  • Experience of Web Services (eg REST, SOAP, XML-RPC)
  • Knowledge of web site internationalisation issues and experience developing web sites in multiple languages particularly in Europe.
  • Use of the following technologies: XML/XSLT, Perl, Microformats, JSON, Flash/Flex
  • Experience developing functionality/applications by assembling existing code modules

Responsibilities

You will work closely with Information Architects, Visual Designers, User Researchers, Software Engineers, and Product Managers to ensure that our web based products in Europe provide the best possible experience for our users.