Using a Web Service in the Dashboard


In this task, you will replace the three <mx:HTTPService> tags with a single <mx:WebService> tag for retrieving the data for the Dashboard. The <mx:WebService> tag is pointing to a Server object that has three different methods to retrieve the data that is needed.

There are two ways to call a Web Service in Flex. The first is tag-based; the other is via ActionScript. You will use the <mx:WebService> tag in this task to create a WebService object against which you can call your methods.

1.

If you have not done so already, start your local ColdFusion server.

2.

Open Dashboard.mxml.

3.

Below the script block, locate the first three <mx:HTTPService> tags (salesRPC, typeRPC and compRPC) that get the XML data for the Dashboard and replace them with a single <mx:WebService> tag. Set the id attribute to dashboardWS. Set the wsdl attribute to http://localhost:8300/flexGrocer/cfcs/aggregate.cfc?wsdl. Finally, leave the fault handler the same as what the <mx:HTTPService> used.

<mx:WebService      wsdl="http://localhost:8300/flexGrocer/cfcs/aggregate.cfc?wsdl"   fault="showFault(event)"> </mx:WebService> 


The technology that you are using here is a ColdFusion Web Service. By specifying the wsdl attribute of the tag, you are telling Flex to fetch the definition Web Service Description Language (WSDL) of the Web Service on the first request to the Web Service. You can trap an event called load, which fires when the WSDL file loads successfully.

In Flex, you can use the methods on a Web Service in three ways:

  • Undeclared Method: You use the <mx:WebService> with the id attribute. Flex looks at the loaded WSDL for the method and arguments based on how you call the <mx:WebService> in your ActionScript.

  • Declared Method: You define the operation as a child of the <mx:WebService> tag via the <mx:operation> tag. Arguments are validated by looking into the WSLD.

  • Fully Declared Method: You define the operation and its arguments as a child of the <mx:WebService> tag via the <mx:operation> and <mx:request> tags.

Tip

The data returned from a WebService call is captured via the fault or result event. One of the benefits of declaring the methods/operations on a WebService is that you can apply specific event handlers to each operation.

4.

Create a child <mx:operation> tag inside the <mx:WebService> tag. Give it a name of getTypeSalesData and point the result handler to the typeRPCResult() function, passing the event object as the only parameter.

<mx:operation name="getTypeSalesData" result="typeRPCResult(event)"> </mx:operation> 


This created a method that will return the sales data summarized for each category of food sold. You had a previously defined function typeRPCResult() that was set up to deal with the result (passed in as a variable called event) from the <mx:HTTPService>. You will modify this function later to handle the new format in which the data is returned.

5.

In between the <mx:operation> tags, create an <mx:request> pair.

<mx:operation name="getTypeSalesData" result="typeRPCResult(event)">   <mx:request>   </mx:request> </mx:operation> 


6.

Specify a tag for startDate that binds to startDate.selectedDate and a tag for endDate that binds to endDate.selectedDate.

<mx:request>   <startDate>{startDate.selectedDate}</startDate>   <endDate>{endDate.selectedDate}</endDate> </mx:request> 


What this does is preset the getTypeSalesData() method to always have the arguments containing the right values. Using binding updates the startDate and endDate with the latest selected date from the user.

Tip

Specifying the arguments of the WebService (or RemoteObject) method and then having the values updating via binding can be a very nice way to simplify your calls.

7.

In the script block at the top of the file, add a public variable called selectedType of type String. Default it to All.

[Bindable] public var selectedType:String = "All"; 


This variable will be used to store the category selected in the ComboBox. It is defaulted to All, which is the initial selection criteria. You will update this value later in the lesson.

8.

Create another child <mx:operation> tag, under the close of the last <mx:operation> tag inside the <mx:WebService> tag. Give it a name of getSalesData and point the result handler to the salesRPCResult() function, passing it the event object.

<mx:operation name="getSalesData" result="salesRPCResult(event)"> </mx:operation> 


This method will return the sales data summarized by each day for the selected category of food sold. You had a previously defined the function salesRPCResult() that was setup to deal with the result from the <mx:HTTPService>. You will modify this function later to handle the new format in which the data is returned. This operation will provide data for two of the ChartPods in the Dashboard, both the sales and comparison ones. In the next lesson, you will use this data uniquely when you do the charting.

9.

In between the <mx:operation> tags, create a <mx:request> pair.

<mx:operation name="getSalesData" result="salesRPCResult(event)">   <mx:request>   </mx:request> </mx:operation> 


10.

In between the <mx:request> tags, specify a tag for startDate that binds to startDate.selectedDate, a tag for endDate that binds to endDate.selectedDate, and a category that binds to the public selectedType variable.

<mx:request>   <startDate>{startDate.selectedDate}</startDate>   <endDate>{endDate.selectedDate}</endDate>   <category>{selectedType}</category> </mx:request> 


What this does is preset the getSalesData() method to always have the arguments containing the right values. Using binding updates the startDate and endDate with the latest date the user selected. It also uses the category selected in the ComboBox as the value to filter on (as you will see in the setCat() function you will create later).

Handling Web Service Results

Because the Web Service requests are made external to the Flex application, you need to "listen" for the result back from the server. The WebService class enables you to listen for the result at the WebService object itself or at the individual method definitions via the result event. The event class that is returned to these methods is mx.rpc.events.ResultEvent. Because the server is not returning the sales data presorted, you need to create a sort function that sorts the results before it assigns it into the data provider of the ChartPod.

1.

Still in the Dashboard.mxml, create a private function called sortByDateField that returns an ArrayCollection. The first argument is called aSales of type ArrayCollection, the second argument is called colName and is of type String.

private function sortByDateField(aSales:ArrayCollection, colName:String):ArrayCollection{ } 


The first argument contains the results passed back from the Web Service. The second argument tells the function which field in the result to do the date sort on. You need to provide the second argument because it this will give you the flexibility of sorting on different columns, depending upon which result is returned.

2.

Create a local ArrayCollection variable called salesData and assign it the passed in argument aSales.

private function sortByDateField (aSales:ArrayCollection, colName:String):ArrayCollection{    var salesData:ArrayCollection = aSales; } 


This is used as a pointer to the ArrayCollection passed into the function.

3.

Inside the script block, add an import for the mx.collections.Sort class.

import mx.collections.Sort; 


4.

Inside the sortByDateField method, create a local Sort variable called sort.

private function sortByDateField (aSales:ArrayCollection, colName:String):ArrayCollection{    var salesData:ArrayCollection = aSales;    var sort:Sort = new Sort(); } 


You will use this variable to setup the sort definition for your local ArrayCollection.

5.

Inside the script block, add an import for the mx.collections.SortField class.

import mx.collections.SortField; 


6.

Back inside the sortByDate method, set the fields property of sort as an array with the first entry a new SortField with two arguments passed to its constructor. The first is colName which will specify the field name for the sort and the second is TRue, which will make the sort case-sensitive.

private function sortByDateField (aSales:ArrayCollection, colName:String):ArrayCollection{    var salesData:ArrayCollection = aSales;    var sort:Sort = new Sort();    sort.fields = new Array(new SortField(colName,true)); } 


For each data set that you use, you should specify the field name on which you are sorting.

7.

Assign the local sort variable to the sort property of salesData and refresh the salesData ArrayCollection.

private function sortByDateField (aSales:ArrayCollection, colName:String):ArrayCollection{    var salesData:ArrayCollection = aSales;    var sort:Sort = new Sort();    sort.fields = new Array(new SortField(colName,true));    salesData.sort = sort;    salesData.refresh(); } 


8.

Return the sorted salesData ArrayCollection from the function.

private function sortByDateField (aSales:ArrayCollection, colName:String):ArrayCollection{    var salesData:ArrayCollection = aSales;    var sort:Sort = new Sort();    sort.fields = new Array(new SortField(colName,true));    salesData.sort = sort;    salesData.refresh();    return salesData; } 


9.

Go to the salesRPCResult() function. Use the sortByDateField() function to sort event.result on the DTSALE field and assign the result to sales.dp. You will need to cast event.result into an ArrayCollection before you pass it into the function.

private function salesRPCResult(event:ResultEvent):void{    sales.dp = this.sortByDateField(event.result as ArrayCollection,"DTSALE"); } 


The call to the ColdFusion Web Service returns the sales data as an ArrayCollection, but the result property on the event object is cast as a generic object. To use it in your function, you need to cast it to an ArrayCollection. By doing sorting here, you are making sure that the data is sorted before you pass it to the component. This handler is mapped to the result event of the WebService 's method.

10.

Go to the typeRPCResult() function. Cast the event.result value in an ArrayCollection.

private function typeRPCResult(event:ResultEvent):void{    type.dp = (event.result as ArrayCollection); } 


The call to the ColdFusion Web Service returns the sales data as an ArrayCollection, but the result property on the event object is cast as a generic object. To use the result, you need to cast it as an ArrayCollection. This handler is mapped to the result event of the WebService 's method.

11.

Remove the compRPCResult() function. You will add this functionality to the salesRPCResult() function because both sales.dp and comp.dp now use the same data. Assign comp.dp to the same sorted results as is used to set sales.dp.

private function salesRPCResult(event:ResultEvent):void{    sales.dp = this.sortByDateField(event.result as ArrayCollection,"DTSALE");    comp.dp = this.sortByDateField(event.result as ArrayCollection,"DTSALE"); } 


Because you no longer need the additional Web Service call to get the data for the Sales ChartPod, it makes sense to collapse the setting of the dp properties of the components in one method.

Calling Web Service Methods

You call a Web Service a bit differently then you do an HTTPService, especially based upon how you have defined the WebService. Instead of a standard send() function on the HTTPService, you call the actual send() function on the method reference on the WebService using the wsId.methodName.send() format. In these tasks, you create this WebService with its operations and arguments defined. You are not worried about passing data to the method because the binding is keeping the arguments always current with the right data.

You will need to update your getdata() function to now call the WebService. Currently, you have getdata() being called on the initialization of the Dashboard. You have configured your Web Service to use a start date, an end date, and a category name as a filter to the data. As these values change, you will want to call the getdata() function again.

1.

Still in Dashboard.mxml, go to the geTData() function. Replace the call to the three HTTPService send() functions with the calls to the Web Services' getTypeSalesData.send() and getSalesData.send() methods.

private function getData():void{    dashboardWS.getTypeSalesData.send();    dashboardWS.getSalesData.send(); } 


2.

Create a private function called setCat() that returns void. Have it accept one argument called event of type Event.

private function setCat(event:Event):void{ } 


This function will capture any selection change in the ComboBox, set the selected category, and refresh the data of the Dashboard.

3.

Set the public variable selectedType to the current category name, which is found in ComboBox(event.currentTarget).selectedItem.name. Then call the geTData() function to refresh the data.

private function setCat(event:Event):void{    selectedType = ComboBox(event.currentTarget).selectedItem.name;    getData(); } 


You need to first cast event.currentTarget into a ComboBox so that you can access the text property. In the text property you will find the name of the current category name selected by the user.

4.

On the change event of the catCombo ComboBox, call the setCat() function passing along the event argument.

<mx:ComboBox    dataProvider="{categories}"   change="setCat(event)"   labelField="name"/> 


5.

On the startDate and endDate DateFields call the geTData() function on their change events.

<mx:Label text="Start Date"/> <mx:DateField  change="getData()"/> <mx:Label text="End Date"/> <mx:DateField  change="getData()"/> 


Because you have bound the arguments of the methods on the WebService to the selected dates of these controls, you only need to call the geTData() function because the binding has already updated the method call with the new date values.

6.

Save and run Dashboard.mxml. Notice that the data loads at startup. Select a different Start Date and see how the data refreshes. Do the same for the Category ComboBox and notice that the Type Pod changes (It is located in the bottom-right part of the screen.).

Playing with the controls, you can see how your leverage of binding on the method arguments enabled you to simply call the method in one place without having to worry about getting the data to pass to the server.

When you run the Dashboard with a filter on Category, you should see the following example.




Adobe Flex 2.Training from the Source
Adobe Flex 2: Training from the Source
ISBN: 032142316X
EAN: 2147483647
Year: 2006
Pages: 225

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net