At SitePen, we work very hard to to provide our customers and fellow developers with useful web app development services. We’re currently deconstructing the development of Queued, our Netflix Queue management application built with Dojo and Adobe AIR. Having presented on dojo.deferred and related topics at the Ajax Experience, and having heard that the Queued team ran into a few problems with them, I thought it would be interesting to review problems that are sometimes encountered when using Deferreds. What is the source of these problems, are these problems related to bugs or because there are misunderstandings, and how should we address this going forward?
Have you ever needed to make a GET request containing a complex request only to find out that it exceeds the maximum length that a url can contain when url encoded? Usually URLs come nowhere near the 2k length on IE and certainly not on other browsers where the length limit is 4k. In most cases, switching to using a POST request without the associated payload limits solves the problem. However, POST requests do not get cached. While this is appropriate in most cases where you are sending a large request, in my work I’ve found several cases where I want to make a complex (long) request, but still retain the caching benefits of GET.
In the past I’ve always been able to resort to some alternative, such as splitting up the request into multiple XHR GETs, but in a current project of mine, the alternatives were ugly or had some other drawbacks. Without getting sidetracked in those details, for purposes of this article, we’ll assume there are valid cases for long GET requests and that is the situation we are in.
So your cool new app is perfect, but you want it to lock the user out when the browser hasn’t had focus after 15 minutes? Well that’s easy you think, I’ll just connect to the document’s blur and focus events and be good to go. You quickly add a little bit of code to your Dojo widget:
dojo.connect(dojo.doc, "onblur", this, "onWindowBlur"); dojo.connect(dojo.doc, "onfocus", this, "onWindowFocus");
That should do it you’d think. Launch your app with Firefox and everything is great, easy enough. The same is true with Safari. After reluctantly firing up your Virtual Machine to test Internet Explorer 6, much to your dismay, onfocus events are immediately followed by onfocusout events. You feel the harsh reality that IE6 is going to suck away a bit more of your life.
I recently came across a situation where I needed to manage a set of nodes and widgets to perform a number of visual operations as well as manage some data between the client and a server back end. While this was a custom operation, it was common to a number of different places within the app. Initially, things were quite simple and I managed with a few functions and connections primarily using dojo.query(). In the end, I ended up with a simple way to make a dijit._Templated widget that uses its source node as a template instead.
Widgets can easily take advantage of existing source nodes to define how they might end up rendering. They might use the source nodes to define a data set. They could be widgets that manage a number of child widgets as is done with the various Dijit Layout widgets. However, under normal circumstances, a widget’s source node is replaced by the nodes generated from its template or the original source nodes are moved to a container node within your template. What we are looking for is a way to define a flyweight widget that can encapsulate behaviors and data, provides for dynamic template generation, and retains the utility of dojoAttachPoints and dojoAttachEvents from the templating system.
In my previous post on the Dojo Object Harness (DOH), I discussed how to write unit tests for custom code in custom places. Alex and Dylan both suggested that I write a follow up post describing how to write asynchronous tests. Lets skip the formalities, and get right to it.
The easiest tests (the synchronous ones) are easy to understand. They simply contain one or more functions that exercise a test condition and then (or while) evaluate the results of the exercises to see if they match a an expected value. For example,
Many Dojo developers are aware of the Dojo Objective Harness (DOH) that the Dojo Toolkit uses for unit testing. Many people, however, want to use DOH for testing their own code or even non-Dojo code that they have written. While DOH has always supported this, there currently aren’t many examples of doing so. Let’s see if we can help that out.
Out of the box, DOH has supported custom code since the beginning. Tests can include any custom namespaces or code by easily using standard JS techniques. Coming to an understanding of how custom namespaces work with Dojo and how and when DOH loads tests will help us illustrate how you can take advantage of DOH in your own code.
It’s not very often that I get to work on some software that has the potential to appeal to developers, testers, designers, and the marketing team all at once. And of course when I do get to work on something like that, it usually means there is a significant amount of pressure to get it done and done quickly. My work on dojox.analytics has been one of those rare instances when I’ve been able to work in peace on writing simple and useful code that can entertain a wide variety of use cases.
While I’m sure there are plenty of others who have had success ridding themselves of apility, very few places describe how this can be accomplished. I initially found an old post which described the basics of connecting directly to Google AdWords with the native Soap support in PHP. What I needed to create was a very lightweight library for communicating with the various ad networks. I didn’t want to define full class structures for each of the many, many types that the various ad networks have. So I set off to create a simple set of libraries for communicating with each network using PHP 5’s native Soap capabilities.
MSN, no problem…done.
Yahoo, no problem…done.
Google, no proble..err wait almost no problem.
Google went along smoothly as with the other networks until I hit a roadblock. In a few circumstances, Google uses inheritance with their complexTypes. For example, a TextAd is an extension of an Ad. In my simple code, I was creating an associative array with the appropriate structure for a TextAd and sending it off to __soapCall() as the parameter. In this particular case, I noticed (by receiving exceptions from Google) that only the properties that were part of the Ad were being encoded in the Soap envelope. The properties that were specific to TextAd were getting dropped.
After a couple hours of searching and experimentation, I found little that seemed to point me in the correct direction. I had tried to use the SoapVar, but there was very little documentation and fewer examples. However, I finally stumbled upon the relatively simple answer and here I am to document it so that the next poor soul traveling down this path will get there faster than I did.