Working with external data



The runtime includes mechanisms for loading data from external sources. Those sources can be static content such as text files, or dynamic content, such as content generated by a web script that retrieves data from a database. The data can be formatted in a variety of ways, and the runtime provides functionality for decoding and accessing the data. You can also send data to the external server as part of the process of retrieving data.

Using the URLLoader and URLVariables classes

The runtime includes the URLLoader and URLVariables classes for loading external data. The URLLoader class downloads data from a URL as text, binary data, or URL-encoded variables. The URLLoader class is useful for downloading text files, XML, or other information to use in AIR applications. The URLLoader class takes advantage of the runtime event-handling model, which allows you to listen for such events as complete, httpStatus, ioError, open, progress, and securityError.

The URLLoader data is not available until the download has completed. You can monitor the progress of the download (bytes loaded and bytes total) by listening for the progress event to be dispatched, although if a file loads too quickly a progress event may not be dispatched. When a file has successfully downloaded, the complete event is dispatched. The loaded data is decoded from UTF-8 or UTF-16 encoding into a string.

Note: If no value is set for URLRequest.contentType, values are sent as application/x-www-form-urlencoded.

The URLLoader.load() method (and optionally the URLLoader class’s constructor) takes a single parameter, request, which is a URLRequest instance. A URLRequest instance contains all of the information for a single HTTP request, such as the target URL, request method (such as GET or POST), additional header information, and the MIME type (for example, when you upload XML content).

For example, to upload an XML packet to a server-side script, you could use the following code:

var secondsUTC = new Date().time; 
var dataXML = "<login>" 
                    + "<time>" + secondsUTC + "</time>" 
                    + "<username>Ernie</username>" 
                    + "<password>guru</password>" 
                + "</login>"; 
var request = new air.URLRequest("http://www.example.com/login.cfm"); 
request.contentType = "text/xml"; 
request.data = dataXML; 
request.method = air.URLRequestMethod.POST; 
var loader = new air.URLLoader(); 
loader.load(request);

The previous code creates an XML instance named dataXML that contains an XML packet to be sent to the server. Next, you set the URLRequest contentType property to "text/xml" and set the URLRequest data property to the contents of the XML packet. Finally, you create a URLLoader instance and send the request to the remote script by using the URLLoader.load() method.

There are three ways in which you can specify parameters to pass in a URL request:

  • Within the URLVariables constructor

  • Within the URLVariables.decode() method

  • As specific properties within the URLVariables object itself

When you define variables within the URLVariables constructor or within the URLVariables.decode() method, you need to make sure that you URL-encode the ampersand character because it has a special meaning and acts as a delimiter. For example, when you pass an ampersand, you need to URL-encode the ampersand by changing it from & to %26 because the ampersand acts as a delimiter for parameters.

Loading data from external network documents

The following snippet creates a URLRequest and URLLoader object, which loads the contents of a text file on the network:

var request = new air.URLRequest("http://www.example.com/data/params.txt"); 
var loader = new air.URLLoader(); 
loader.load(request);

By default, if you do not define a request method, the runtime loads the content using the HTTP GET method. If you want to send the data using the POST method, you need to set the request.method property to POST using the static constant URLRequestMethod.POST, as the following code shows:

var request = new air.URLRequest("http://www.example.com/sendfeedback.cfm"); 
request.method = air.URLRequestMethod.POST;

The external document, params.txt, that is loaded at run time contains the following data:

monthNames=January,February,March,April,May,June,July,August,September,October,November,December&dayNames=Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday

The file contains two parameters, monthNames and dayNames. Each parameter contains a comma-separated list that is parsed as strings. You can split this list into an array using the String.split() method.

Tip: Avoid using reserved words or language constructs as variable names in external data files, because doing so makes reading and debugging your code more difficult.

Once the data has loaded, the Event.COMPLETE event is dispatched, and the contents of the external document are available to use in the URLLoader’s data property, as the following code shows:

function completeHandler(event) 
{ 
    var loader2 = event.target; 
    air.trace(loader2.data); 
}

If the remote document contains name-value pairs, you can parse the data using the URLVariables class by passing in the contents of the loaded file, as follows:

function completeHandler(event) 
{ 
    var loader2 = event.target; 
    var variables = new air.URLVariables(loader2.data); 
    air.trace(variables.dayNames); 
}

Each name-value pair from the external file is created as a property in the URLVariables object. Each property within the variables object in the previous code sample is treated as a string. If the value of the name-value pair is a list of items, you can convert the string into an array by calling the String.split() method, as follows:

var dayNameArray = variables.dayNames.split(",");
Tip: If you are loading numeric data from external text files, you need to convert the values into numeric values by using a top-level function, such as parseInt(), parseFloat(), and Number().

Instead of loading the contents of the remote file as a string and creating a URLVariables object, you could instead set the URLLoader.dataFormat property to one of the static properties found in the URLLoaderDataFormat class. The three possible values for the URLLoader.dataFormat property are as follows:

Value

Description

air.URLLoaderDataFormat.BINARY

The URLLoader.data property contains binary data stored in a ByteArray object.

air.URLLoaderDataFormat.TEXT

The URLLoader.data property contains text in a String object.

air.URLLoaderDataFormat.VARIABLES

The URLLoader.data property contains URL-encoded variables stored in a URLVariables object.

The following code demonstrates how setting the URLLoader.dataFormat property to air.URLLoaderDataFormat.VARIABLES allows you to automatically parse loaded data into a URLVariables object:

var request = new air.URLRequest("http://www.example.com/params.txt"); 
var variables = new air.URLLoader(); 
variables.dataFormat = air.URLLoaderDataFormat.VARIABLES; 
variables.addEventListener(air.Event.COMPLETE, completeHandler); 
try 
{ 
    variables.load(request); 
}  
catch (error) 
{ 
    air.trace("Unable to load URL: " + error); 
} 
 
function completeHandler(event) 
{ 
    var loader = event.target; 
    air.trace(loader.data.dayNames); 
}
Note: The default value for URLLoader.dataFormat is air.URLLoaderDataFormat.TEXT.

As the following example shows, loading XML from an external file is the same as loading URLVariables. You can create a URLRequest instance and a URLLoader instance and use them to download a remote XML document. When the file has completely downloaded, the complete event is dispatched and the trace() function outputs the contents of the file to the command line.

 
var request = new air.URLRequest("http://www.example.com/data.xml"); 
var loader = new air.URLLoader(); 
loader.addEventListener(air.Event.COMPLETE, completeHandler); 
loader.load(request); 
 
function completeHandler(event) 
{ 
    var dataXML = event.target.data; 
    air.trace(dataXML); 
}

Communicating with external scripts

In addition to loading external data files, you can also use the URLVariables class to send variables to a server and process the server’s response. This is useful, for example, if you are programming a game and want to send the user’s score to a server to calculate whether it should be added to the high scores list, or even send a user’s login information to a server for validation. A server-side script can process the user name and password, validate it against a database, and return confirmation of whether the user-supplied credentials are valid.

The following snippet creates a URLVariables object named variables, which creates a variable called name. Next, a URLRequest object is created that specifies the URL of the server-side script to send the variables to. Then you set the method property of the URLRequest object to send the variables as an HTTP POST request. To add the URLVariables object to the URL request, you set the data property of the URLRequest object to the URLVariables object created earlier. Finally, the URLLoader instance is created and the URLLoader.load() method is invoked, which initiates the request.

var variables = new air.URLVariables("name=Franklin"); 
var request = new air.URLRequest(); 
request.url = "http://www.example.com/greeting.cfm"; 
request.method = air.URLRequestMethod.POST; 
request.data = variables; 
var loader = new air.URLLoader(); 
loader.dataFormat = air.URLLoaderDataFormat.VARIABLES; 
loader.addEventListener(air.Event.COMPLETE, completeHandler); 
try 
{ 
    loader.load(request); 
} 
catch (error) 
{ 
    air.trace("Unable to load URL"); 
} 
 
function completeHandler(event) 
{ 
    air.trace(event.target.data.welcomeMessage); 
}

The following code contains the contents of the Adobe® ColdFusion® greeting.cfm document used in the previous example:

<cfif NOT IsDefined("Form.name") OR Len(Trim(Form.Name)) EQ 0> 
    <cfset Form.Name = "Stranger" /> 
</cfif> 
<cfoutput>welcomeMessage=#UrlEncodedFormat("Welcome, " & Form.name)# 
</cfoutput>