Download the public beta of ColdFusion Splendor from here

Yesterday I posted an example of how to take picture and upload it to CF server in a mobile app using CFMobile features. One of the APIs this example used was to upload file to CF server -

cfclient.file.upload(imageFilePath, localStorage.serverUrl,
			onFileUploaded, uploadError, uploadOptions 


onFileUpload is a success callback function and uploadError is an error callback function. To this Sean Corfield tweeted at me following question - 

surprised cfclient.file.upload needs callbacks - isn't the point of cfclient to avoid writing those?

I was going to reply to Sean directly but then thought that others might have the same question, so decided to answer it in this blog post.

So yes, one of the ways cfclient tries to simplify writing code for mobile applications is by providing synchronous function access to some of the asynchronous PhoneGap APIs. However it does not do so in two cases - 1. function call leaves device boundary 2. function requires event based processing.

File upload APIs falls in the first category - it makes call to a server and you certainly don't want the mobile application to get blocked till it gets response from the server.
Example of function in the second category is cfclient.geolocation.watchPosition, which i used in my post 'CFMobile Example – Using Geolocation APIs in ColdFusion Splendor'. This function takes action based on an event - when position changes, so it takes callback function as an argument.

But many APIs for Database, Contacts, File, Camera need not be asynchronous. If you develop standalone desktop applications, do you access database  asynchronously ? I guess, most likely not. 

Specifically regarding file upload function, we debated if we should include it in cfclient, because it is vary similar to the actual PhoneGap file upload function. And we decided to include it because - 1. for the sake of completeness and 2. you can get code assist for it in Thunder.

-Ram Kulkarni

5 Comments to “Why does cfclient file upload API take callback functions?”

  1. Sean Corfield
    Given that cfclient is a compiler from CFML to JS, this would have been a great opportunity to compile inline synchronous CFML to closure-based asynchronous JS in my opinion.

    (and, yes, I know there are some subtle issues here - but compilers and runtime systems are my area of expertise so I also know this possible :)

    The more I see of cfclient, the worse my opinion of it gets...
  2. Ram Kulkarni
    Can you give an example of compiling inline synchronous CFML to closure-based asynchronous JS?
  3. Dan G. Switzer, II
    If the purpose is to "simplify" and "mask complexity", you could have turned the code into promises behind the scenes or even as closures as Sean indicated.
  4. Sean Corfield
    As Dan indicates, you would have to do flow analysis of the cfclient block and lift code segments into promises or closures. Essentially transforming linear code into CPS, to allow for conditionals etc.

    You'd also want clear guidelines on how the "slow" APIs should be used to enable the appropriate flow analysis. For example mandating if ( someCall(..) ) { ..success block..} else { ..failure block.. } or something similar. Allowing for assignment to a boolean and later testing would rely on flow analysis and lifting of any intermediate code into CPS chains so that it could be executed asynchronously.

    Data flow analysis would also allow you to reorganize code to identify non-dependent segments that could be lifted above the call or just chained into the generated callbacks.
  5. Ram Kulkarni
    What you are talking about is code generation part. FYI, we do code flow analysis and chaining of callbacks (just like Promises do for asynchronous functions) before generating JS code.

    What I was taking about was simplifying APIs that the end user is going to use and I think we have provided the simplest form of APIs to call asynchronous functions.

Leave a Comment

Leave this field empty: