20
Apr
09

Server result, who called?

I ran into a problem the other day. We integrate our flash application with a server-side image archive, allowing browsing from the flash front-end. That means loading a tree structure and contents of all folders. We only load the structure initially to optimize bandwidth usage – data about the contents of folder is loaded when the user selects a folder. That means the first time I select a folder for this session, a call to the server is made requesting the content of that folder. A call-back function is set which handles placing the data into the dataProvider and updating the view.

So far, so good. But there was a snag – to further optimise transferred data, we only return data about the images in the folder, not what folder they are in. So the call back function has no way of telling where to put the data unless we make sure that there’s only one call for folder contents at a time. That kind of synchronicity is OK for loading contents for a list of folders at e.g. start up, but as a response to user input, it would mean a clunky user experience. Having to wait 1.5 seconds for a folder to load before selecting the next? It would feel like lag. Clearly not the best option.

Here’s the initial code:

public function loadAssets( nodeId:String):void {
	var responder:Responder = new Responder(responderResult, loadAssets_Error);
	connection.call(config.getServerURLs().assetMethod, responder, nodeId)
}
private function loadAssets_Result(result:Object):void {
	// asset list
	var resultList:Array = result as Array;
	dispatchEvent(new MspEvent(MEDIA_FILES_LOADED, resultList));
}

If loadAssets is called when a folder is selected by the user and the user clicks on a new folder before the first has finished loading, we have no way of telling which folder the received result belongs to. Could make for some seriously frustrated and confused end users. Who will call support. Who will come to the developer (you) and ask what is going on.  And if you test nice and slowly or on a good, fast connection, the error won’t occur because loading would have finished before the next folder is selected.  Bugs due to timing issues – arg!

The solution is an anonymous function:

msp_public function loadAssets(nodeId:String):void {
    // create a temporary responder function to be able to remember nodeId.
    var responderResult:Function = function (result:Object):void {
        loadAssets_Result(result, nodeId);
    }
    var responder:Responder = new Responder(responderResult, loadAssets_Error);
    connection.call(config.getServerURLs().assetMethod, responder, nodeId)
}
private function loadAssets_Result(result:Object, nodeId:String = null):void {
    // asset list
    var resultList:Array = result as Array;            

    // event object - both file list and node info
    var toEvent:Object = {nodeId:nodeId, assets:fileList}
    dispatchEvent(new MspEvent(MEDIA_FILES_LOADED, toEvent));
}

We store the parameters for the call in an anonymous function that acts as a relay to the final responder function that does the parsing. The responderResult function will live as long as it’s referenced by the responder, which in turn will live till the connection.call has returned. A nice clean way to handle the problem with very little overhead.

This is just an example, the method could be expanded on and I know we should have a custom event type for this to tidy things up, but that would make the example harder to read.

Advertisements

0 Responses to “Server result, who called?”



  1. Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: