AOL Pictures and Flex

The AOL Pictures CFC I demonstrated last week hopefully opened up your curiosity to explore its possibilities. While we could certainly be happy with a standard DHTML application using any number of toolkits, this week we'll take it one step further and feed our pictures to an Adobe Flex application. Sure I love JavaScript, but Flex is pretty cool too.

Rather than serve as a comprehensive overview of Adobe Flex, this post will attempt to demonstrate some of the core capability this technology offers. The documentation from Adobe is quite good and will guide you the rest of the way. This demonstration will attempt to duplicate our example from last week but implement the presentation using Flex.

Flex Crash Course

Flex is basically the programmers gateway to building applications for the Flash player platform. It is composed of a suite of tools including an SDK, complete IDE based on the Eclipse platform, as well as add-on components such as advanced data handling and charting capability. You develop Flex applications using MXML and ActionScript. While MXML (an XML-based user interface markup language) generally handles layout, ActionScript provides much of the dynamic behavior. To get started, I would recommend visiting the following links:

To follow along with the examples, you will need to at least download the Flex SDK so you can compile the code as well as have Flash Player 9.0 installed for your target browser. The example is composed of three parts:

  1. A ColdFusion page which provides AOL Pictures data as an XML feed.
  2. A Flex application, compiled and deployed as a SWF file.
  3. An additional webpage used to carry the SWF file.

The ColdFusion XML Feed

We'll start by examining the XML feed coming from ColdFusion, Listing 1 below is the complete source code to enable this service.


<!--- create an AOL.Pictures component instance --->
<cfset obj_aolPictures = CreateObject( "component", "AOL.Pictures" ).init() />
<cfset obj_aolPictures.setDevId( "someAOLDevId" ) />

<cfxml variable="xml_aolPictures">
	<cfif url.serviceName eq "getAlbumList">
    	<!--- get the album listing for the winterWooHoo login --->
		<cfset st_albumList = obj_aolPictures.getAlbumList( "winterWooHoo" ) />

        <response>
            <albums>
            <cfloop from="1" to="#ArrayLen( st_albumList.albums )#" index="i">
                <cfoutput>
                <album albumId="#st_albumList.albums[i].id#" albumName="#st_albumList.albums[i].title#" />   
                </cfoutput>
            </cfloop>
            </albums>
        </response>
    
    <cfelseif url.serviceName eq "getPicturesByAlbumId">
    
    	<!--- get the pictures --->
        <cfset st_pictures = obj_aolPictures.getPicturesByAlbumId( url.albumId ) />
    
     	<response>
        	<pictures>
            	<cfif isDefined( "st_pictures.response.data.pictures" )>
                <cfloop from="1" to="#ArrayLen( st_pictures.response.data.pictures )#" index="i">
                    <cfoutput>
                    <picture>#st_pictures.response.data.pictures[i].sizes[1].url#</picture>
                    </cfoutput>
                </cfloop>
                </cfif>
            </pictures>
        </response>

    </cfif>
</cfxml>

<!--- print out the result --->
<cfoutput>#toString( xml_aolPictures )#</cfoutput>
Listing 1 - AOL Pictures XML Feed

The ColdFusion code in Listing 1 provides the ability to query for two types of information. The first is a listing of albums based on the hardcoded owner winterWooHoo. The album list will return an XML feed with the following specs:

<?xml version="1.0" encoding="utf-8"?>
<response>
	<albums>
    	<album albumId="someAlbumId1" albumName="First Album" />
        <album albumId="someAlbumId2" albumName="Second Album" />
        <!-- and so on -->
    </albums>
</response>

The second capability is a listing of pictures based on an album id passed as a querystring parameter. The picture list will return an XML feed with the following specs:

<?xml version="1.0" encoding="utf-8"?>
<response>
	<pictures>
    	<picture>http://pathToSomePicture1</picture>
        <picture>http://pathToSomePicture2</picture>
        <!-- and so on -->
    </pictures>
</response>	

The ColdFusion is very similar to last week's, we're just now providing it as XML.

On to Flex

Although the Flex application is relatively compact at less than 100 lines of code, it packs quite a bit of functionality. I will be revealing logical blocks of the Flex code to aid in digestion. We'll start with the layout as shown in Listing 2 below.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="800" height="600" creationComplete="http_getAlbumList.send();">

	<mx:Panel title="AOL Pictures" width="100%" height="100%" paddingLeft="20" paddingTop="20">
    	<mx:VBox>
        	<mx:HBox>
            	<mx:Label text="Album List:" />
        		<mx:ComboBox id="albumList"
                			 dataProvider="{ http_getAlbumList.lastResult.response.albums.album }"
                             labelField="albumName"
                             close="http_getPicturesByAlbumId.send();" />
            </mx:HBox>
            
            <mx:Tile id="albumPictures" direction="vertical" />  
        </mx:VBox>
    </mx:Panel>
    
</mx:Application>    
Listing 2 - Flex layout

The key aspects of this code are as follows:

  • It's written in MXML.
  • The <mx:Application /> tag is always the root. All subsequent Flex code I present here will reside as a child to the <mx:Application /> tag.
  • The <mx:Panel /> tag is a builtin UI component, we're using it as a container.
  • The <mx:VBox /> and <mx:HBox /> are also builtin components which are used to easily group and display child components in either vertical (VBox) or horizontal (HBox) fashion.
  • The <mx:Tile /> control will group it's children in equal tiles. In this case, the children will be image assets.
  • Don't let the additional attributes throw you off. This code basically lays out a text label, text input box, button, and a combo box. We'll discuss the other features next.
  • Once the Flex application is compiled, we can hook it in to a web page using the <embed /> and <object /> tags.

The default user interface of the Flex application may be seen in Figure 1 below.


Figure 1 - Flex UI

Having shown our layout, we may now demonstrate the methods used to retrieve the remote information provided by the ColdFusion XML feed in Listing 3 below.

<!-- service used to retrieve the album list -->
<mx:HTTPService id="http_getAlbumList"
                url="http://localhost/cfXMLFeed.cfm?serviceName=getAlbumList" />
                
<!-- service used to get the pictures for the selected album -->
<mx:HTTPService id="http_getPicturesByAlbumId"
                url="http://localhost/cfXMLFeed.cfm?serviceName=getPicturesByAlbumId"
                result="loadPictures( event );">
    <!-- send the selected album id as an argument -->
    <mx:request>
        <albumId>
            { albumList.selectedItem.albumId }
        </albumId>
    </mx:request>                    
</mx:HTTPService>
Listing 3 - Flex HTTPService Definitions

The key aspects of this code are as follows:

  • <mx:HTTPService /> is basically used to configure HTTP requests.
  • Two requests are defined, one to retrieve the album list for winterWooHoo and the other to retrieve the pictures based on an album id passed.
  • The album id parameter is the value of the currently selected item in the combo box UI control.
  • The result attribute of the <mx:HTTPService /> component defines an ActionScript function which will fire when the result from the HTTP request returns.

The final piece to the Flex application is an ActionScript script block shown in Listing 4 below.

<mx:Script>
<![CDATA[
    import mx.controls.Image;
    import mx.collections.ArrayCollection;

    // used to load the pictures retrieved from the selected album to the Tile control.
    private function loadPictures( event:Event ):void {
        
        try {
            // define an array of picture url's
            var arr_pictures:ArrayCollection = http_getPicturesByAlbumId.lastResult.response.pictures.picture;
        }
        catch( errObject:Error ) {
            // clean up the Tile control, notify user, exit.
            albumPictures.removeAllChildren();
            mx.controls.Alert.show( "There are no pictures to display.", "AOL Pictures" );
            return;
        }
        
        // initialize the Tile control
        albumPictures.removeAllChildren();
        
        // load the new pictures to the Tile control
        for( var i:int = 0; i < arr_pictures.length; i++ ) {
        
            // create a new temporary image
            var tmpImage:Image = new Image();
            tmpImage.source = arr_pictures[i];
            
            // tack the image on to the Tile
            albumPictures.addChild( tmpImage );
        }
        
        return;
    }
]]>
</mx:Script>
Listing 4 - ActionScript block

Listing 4 demonstrates the function loadPictures which fires when the picture result comes back. The XML data returned is assigned as an ActionScript ArrayCollection data structure, which is looped over to dynamically create and assign to the Tile control for display. If there is a problem during processing, the Tile control is cleaned up and an alert message is shown to the user. Sample picture output may be seen in Figure 2 below.


Figure 2 - Sample picture output

This post demonstrated some of the concepts involved in constructing a Flex application to include dynamic elements such as remote querying and loading of image assets. It was not meant to demonstrate best practices or recommended architecture. To leverage the AOL Pictures CFC and create a simple and sexy Flex application is less than 200 lines of code is an exciting idea worth pursuing.

Great Resource!

Brice -

That's a great quick and useful tutorial on the technology. Great job!

j

FABridge resources

The FABridge is definitely very cool. I had found some of the resources on it a little thin so I decided to write an article on my website entitled 10 Steps to Mastering the Adobe Flex-Ajax Bridge (FABridge). Check it out if you like, it's a complete tutorial on using this library and includes code downloads and cheatsheets.

Flex-Ajax-Bridge

Adobe recently released the Flex AJAX Bridge (FABridge). According to the Adobe Labs wiki its a small, unobtrusive code library that you can insert into an Adobe Flex application, a Flex component, or even an empty SWF file to expose it to scripting in the browser. Looks like an interesting way to integrate Flex and Javascript!