RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Build a Simple Map Client with SOAP in Flash Builder 4, Part I : Page 2

The new data service tools in Flash Builder automate enough of the grunt work that using a SOAP web service is almost trivial.


Examine the Generated Form

When the wizard finishes, SearchForm.mxml will be augmented with the generated form, a function in the Script block to handle the Submit button, and two object instances in the Declarations block. Let's start with a quick look at the form:
<mx:Form defaultButton="{button}">
  <mx:FormItem label="PlaceName">
    <s:TextInput id="placeNameTextInput"/>
 <mx:FormItem label="MaxItems">    <s:TextInput id="maxItemsTextInput"/>  </mx:FormItem>  <mx:FormItem label="ImagePresence">    <mx:CheckBox id="imagePresenceCheckBox"/>
 </mx:FormItem>    <s:Button label="GetPlaceList" id="button"              click="button_clickHandler
(event)"/> </mx:Form>
Each input parameter for TerraService's GetPlaceList operation has a corresponding form item:
    * In the placeNameTextInput field, users type a location/land name like "Denver, CO" or "Statue of Liberty, New York."
    * The maxItemsTextInput field is used to specify an upper limit of places returned in the search results.
    * The imagePresenceCheckBox indicates whether to limit the search results to places with available imagery.
For the sake of your own testing convenience, I recommend that you set a default value on the latter two form items. Add text="5" to the maxItemsTextInput and selected="true" to the imagePresenceCheckBox. Eventually -- when you're done experimenting -- you may want to hide these two form inputs altogether. Add visible="false" and includeInLayout="false" to both components' to hide them away with minimal refactoring. The project available for download at the end of this article has a more aesthetic version of this form, as well.

Examine the Generated Declarations

The declarations block in SearchForm.mxml has two new instances inserted by the form generator:
      <terraservice2:TerraService2 id="terraService2" fault="Alert.show
(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
     <s:CallResponder id="GetPlaceListResult"/>
The instance of the TerraService2 service is a local proxy object that the Connect to Data/Service Wizard generates. When GetPlaceList is called, a non-blocking SOAP request is sent to the remote TerraService. The method itself immediately returns a callback token that is populated when the asynchronous response occurs. (If you're familiar with Asynchronous JavaScript and XML [Ajax] concepts, this is old hat.)

The fault attribute on the TerraService2 instance is set to handle any error responses with a generic alert. The showBusyCursor attribute is a convenient mechanism for reminding users that a response is still pending.

Right-click the TerraService2 class, and then click Go to Definition. Note that Flash Builder leaves this empty subclass as a place for customized behavior. Go to the definition of the super class reference _Super_TerraService2 to see where the real service-specific code has been generated.

Scroll down to the definition for the GetPlaceList method. The comment block is extremely informative, describing how the method should be used:
/** This method is a generated wrapper used to call the 
'GetPlaceList' operation.
It returns an AsyncToken whose result property will be populated with the result of
the operation when the server response is received. To use this result from MXML code, define a CallResponder component and assign its token
property to this method's return value. You can then bind to CallResponder.lastResult or listen for the CallResponder.result or fault events. @see mx.rpc.AsyncToken @see mx.rpc.CallResponder @return an AsyncToken whose result property will be populated with the result of the operation when the
server response is received. */           public function GetPlaceList(placeName:String, MaxItems:int,                       imagePresence:Boolean) : AsyncToken { … }
Returning to the generated declarations in SearchForm.mxml, below the TerraService2 declaration is a CallResponder instance. This instance will be populated when TerraService responds to the request. This operation is done in the generated Script block, so that's where we should look next.

Examine the Generated Script

The Script block in SearchForm.mxml now contains a simple function that is called when users click Search:
protected function button_clickHandler(event:MouseEvent):void
  GetPlaceListResult.token = terraService2.GetPlaceList( 
When the button_clickHandler is invoked, the TerraService2 instance's GetPlaceList method is called with input values from the form. The return AsyncToken value is set on the GetPlaceListResult call responder. To display the search results, simply use the lastResults property on GetPlaceListResult as the data provider for a List.

To display the search results, use a simple list and assign the data provider to the lastResults property on GetPlaceListResult. Add the component shown here below the <Form /> in SearchResults.mxml:
<s:List id="placeList" dataProvider="{GetPlaceListResult.lastResult}"
        labelFunction="placeLabel" width="590" height="70" color="#0000FF" 
        textDecoration="underline" textAlign="center" borderVisible="false">
    <s:TileLayout horizontalAlign="center" 
                  columnAlign="justifyUsingWidth" />
The heart of this component is really just a List with a dataProvider and a labelFunction. The rest of the attributes and the layout are there for aesthetic reasons.

A custom labelFunction is needed, because the search results are an array of PlaceFacts value objects. (These were generated when you used the Connect to Data/Service Wizard.) They don't have a useful toString() method, so provide a simple placeLabel function. Add the following function to the Script block in SearchForm.mxml:
protected function placeLabel(value:Object):String 
  return value._Place.City + ", " + value._Place.State;
The TerraService uses the City attribute on a Place object to hold either an actual city name or a landmark name. So, the computed label will work for equally well for "Denver, Colorado" and "Statue of Liberty, New York."

Try it out

So far, you've connected to the web service, generated a search form, and added a List component to display the results. It is time to try it out for yourself:
    1. Click Run > Run to build and run the TerraClient project.
    2. If the Run As window appears, select the Web Application option. Click OK.
When the TerraClient loads in your web browser, you'll see the search form. Enter a city and state in the PlaceName field. If you didn't specify a default value in the form for MaxItems, you'll need to enter a number between 1 and 100, inclusive. Figure 4 shows what the form and search results look like when searching for "San Jose, CA" with the initial TerraClient.

Figure 4. The search form in action

Wrapping Up

The new tools available in Flash Builder handle a lot of the grunt work needed to use remote SOAP web services. Once you get familiar with the wizards introduced in this article, you can probably get through every step thus far in less than 5 minutes. More importantly, you've started to see what's behind the "magic" and how to use it for your own projects.

For your convenience, you can download and import a version of the project so far: terraclient_part1.fxp. You can use it to check against your own work to make sure everything is correct thus far.

TerraClient isn't finished just yet, however. In part 2, you'll need to use one of the search results to build a tiled map display. You'll use what you've learned in here to make multiple asynchronous SOAP requests and handle the results.

Email AuthorEmail Author
Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date