In this tutorial you will create a Flex application that searches the eBay site for items matching a Shopping API advanced query. The sample application displays the results as a list of links to the item listings on the eBay site. The application uses the eBay Shopping API, which enables developers to interact with the eBay API servers using a simple URL over HTTP.
Think of this tutorial as "Hello World" for eBay's Shopping Web Service. It shows you how easy it is to interact with the Shopping Web Service. When you complete the tutorial, you will have an application that looks like this when it runs:
The example above is actually made up of three search widgets - one to find items in the $0-$50 range, one to find items in the $50 - $200 range, and one to find items in the $201 - $500 range. This tutorial will explain how to create the first widget and then how to modify it to create the widgets with the other sets of results.
Before we begin our step-by-step procedure, let's go over the basics of using the Flex/Flash SDK 587. With this SDK, you can design applications or widgets using pre-created classes that correspond to the calls in the eBay Shopping Web Service.
If you look in the /src folder in your Flex/Flash SDK, you will see these call-specific .as files.
Since each of the Shopping Web Service calls is available as an .as file, you can easily create an application that
incorporates any of these calls, without writing them from scratch. Each call-specific .as file instantiates the
types used by that call.
Within the src/com/ebay/shoppingservice directory, you will see all of the type files used by the
eBay Shopping Web Service (in the form of .as files).
Please refer to the Flex Developer Guide for general information about how to use the Flex/Flash SDK.
After running this tutorial, if you start creating your own search widgets or applications that bring traffic to the eBay web site, you can earn money through the eBay Affiliate Program. For notes about the tutorial and the eBay Affiliate Program, see Notes and next steps.
There are nine main steps for this tutorial:
Step 1: Create a Flex Builder 2 project file
Step 2: Create the Main .mxml appliction file
Step 3: Set up the Shopping Web Service calls
Step 4: Setup the callback functions
Step 5: Add code to display the results
Step 6: Create the onApplicationComplete() ("main") function
Step 7: Review and modify the SampleUtils file
This tutorial was designed to explain the FindItemsAdvanced sample files, located within the /Samples/Flex/FindItemsAdvanced directory of your Flex/Flash SDK, and to help you create your own applications based on these samples. Some of the steps may include a sub-set of the code that is actually in the sample, in order to keep the tutorial concise. Please compare the tutorial to the samples as you proceed.
You need to create a new Flex project with a main application file (file with .mxml extension and a blue icon in the Flex Builder 2 navigator window) before you can create the rest of your Flex application or widget. To create a new Flex project:
Note: You may alternatively create a Flex project directly using the Flex/Flash SDK sample source:
It is recommended that you create an application using the Flex/Flash SDK sample source first, before you create your own application.
Create a main .mxml application file that will contain your flex calls, parse the results of those calls, and pass the retrieved information to a UI display function (Flex builder 2 creates a blank .mxml file by default. You can use that file). We are referring to this file as, "FindItemsAdvanced.mxml" in this tutorial.
Let's begin by importing the packages for all of the eBay Flex/Flash SDK classes and other Flex components classes that are used by the sample created in this tutorial:
<mx:Script> <![CDATA[ import mx.collections.ArrayCollection; import com.ebay.shoppingservice.*; import mx.controls.Alert; import util.eBayUtil; import com.ebay.events.Fault; import com.ebay.events.FaultEvent;
Now let's create a service variable and a queryKeywords variable
private var service:Shopping; private var queryKeywords:String;
Then create displayItem variables to store a list of items and an errorMessage variable. You can bind these variables to UI elements directly, since these are "Bindable variables".
/** * Storing items in price range 0$-50$ * @type ArrayCollection */ [Bindable] private var displayItemsResultOne:ArrayCollection = new ArrayCollection(); /** * Storing items in price range 51$-200$ * @type ArrayCollection */ [Bindable] private var displayItemsResultTwo:ArrayCollection = new ArrayCollection(); /** * Storing items in price range 201$-500$ * @type ArrayCollection */ [Bindable] private var displayItemsResultThree:ArrayCollection = new ArrayCollection(); [Bindable] private var errorMessage:String = "";
In this step, we will set up a function to get the FindItemsAdvanced request object within the FindItemsAdvanced.mxml file. This function takes pmax (the upper limit of the price) and pmin (the lower limit of the price) as parameters within the function. We also need to specify item sort code, item type, query keywords, and the number of items we want to retrieve. This function returns a FindItemsAdvancedRequestType object.
/**
* get FindItemsAdvanced request with specified price range
* @param {int} pmax, upper limit of the price
* @param {int} pmin, lower limit of the price
* @return {FindItemsAdvancedRequestType}
*/
private function getFiaRequest(pmax:int, pmin:int):FindItemsAdvancedRequestType {
var fiaRequest:FindItemsAdvancedRequestType = new FindItemsAdvancedRequestType({
priceMax: {currencyID: CurrencyCodeType.USD, Value: pmax},
priceMin: {currencyID: CurrencyCodeType.USD, Value: pmin},
itemSort: SimpleItemSortCodeType.BestMatch,
QueryKeywords: queryKeywords,
itemType: ItemTypeCodeType.FixedPricedItem,
maxEntries: 10
});
return fiaRequest;
}
Now let's set up a performSearch function to search for items in three different price ranges. First, create a FindItemsAdvancedRequestType object for the price range $0-50, using the getFiaRequest function created above. Then call the findItemsAdvanced method of the service object, pass two parameters to the method - the FindItemsAdvancedRequestType object created above, and a ShoppingCallback object (the next section provides detail about the ShoppingCallback object). Repeat the process for the price range $51-200, and $201-500.
/**
* Invoke findItemsAdvanced shopping api 3 times for each price range
*/
private function performSearch():void {
var fiaRequestOne:FindItemsAdvancedRequestType = this.getFiaRequest(0, 50);
service.findItemsAdvanced(fiaRequestOne, new ShoppingCallback(onSomeItemsReturned("$0-$50",
displayItemsResultOne, itemListOne, priceRange1), onSomeItemsReturnedFailed("$0-$50",
displayItemsResultOne, itemListOne, priceRange1)));
var fiaRequestTwo:FindItemsAdvancedRequestType = this.getFiaRequest(51, 200);
service.findItemsAdvanced(fiaRequestTwo, new ShoppingCallback(onSomeItemsReturned("$51-$200",
displayItemsResultTwo, itemListTwo, priceRange2), onSomeItemsReturnedFailed("$51-$200",
displayItemsResultTwo, itemListTwo, priceRange2)));
var fiaRequestThree:FindItemsAdvancedRequestType = this.getFiaRequest(201, 500);
service.findItemsAdvanced(fiaRequestThree, new ShoppingCallback(onSomeItemsReturned("$201-$500",
displayItemsResultThree, itemListThree, priceRange3), onSomeItemsReturnedFailed("$201-$500",
displayItemsResultThree, itemListThree, priceRange3)));
}
The constructor of the ShoppingCallback object takes two parameters - one is the success callback function and the other is the failure callback function.
If the findItemsAdvanced service call succeeds, we call the success callback function to get a success callback function object. In this tutorial this function is called "onSomeItemsReturned".
/**
* return an items processing callback function,
* actionscript closure is used
* @param {String} range
* @param {ArrayCollection} displayItemsResult
* @param {ItemList} itemList
* @param {Label} priceRange
* @return function
*/
public function onSomeItemsReturned(range: String, displayItemsResult: ArrayCollection, itemList: ItemList, priceRange: Label): Function {
return function(searchResult:FindItemsAdvancedResponseType):void {
var itemArray:Array = getItemArray(searchResult);
for(var i: int = 0; i < itemArray.length; ++i) {
displayItemsResult.addItem(itemArray[i]);
}
resizeDisplayItems(range, displayItemsResult, itemList,
priceRange, searchResult.totalItems);
}
}
On success, the findItemsAdvanced service call will return a list of items in the "searchResult". Now let's create a function to convert the list of items in the search result to an array of items. We'll also create a function to resize the display items, based on the number of items returned.
/**
* filter the returned items
* @param {FindItemsAdvancedResponseType}
* @return {Array}, filtered items
*/
private function getItemArray(searchResult:FindItemsAdvancedResponseType):Array {
var itemArray:Array = new Array();
if(searchResult.ack.value != AckCodeType.Success.value) {
return itemArray;
}
//filter out all items whose listing type is chinese and BuyItNow is false
if (searchResult.searchResult != null && searchResult.searchResult.length > 0) {
var i:int = 0;
var items: Array = (searchResult.searchResult[0] as SearchResultType).itemArray.item;
var count: int = items.length;
itemArray = new Array();
while ( i < count && itemArray.length < 3) {
var item:SimpleItemType = (items[i] as SimpleItemType)
if ( item.listingType.value == ListingTypeCodeType.Chinese.value&& !item.buyItNowAvailable) {
i++;
continue;
}
itemArray.push(item);
i++;
}
}
return itemArray;
}
/**
* adjust the display of data grid
* @param {String} range
* @param {ArrayCollection} displayItemsResult
* @param {ItemList} itemList
* @param {Label} priceRange
*/
private function resizeDisplayItems(range:String, displayItemsResult: ArrayCollection, itemList: ItemList, priceRange: Label, totalItems: int): void {
if (displayItemsResult.length > 0) {
itemList.rowCount = displayItemsResult.length + 1;
priceRange.text = range + " (" + totalItems + " items found)";
} else {
itemListOne.rowCount = 1;
priceRange.text = range + " (no items found)";
}
itemList.height = 50 + 70 * displayItemsResult.length;
}
If the findItemsAdvanced call fails, we call the failure callback function to get a failure callback function object. In this tutorial, this function is called "onSomeItemsReturnedFailed". This failure callback function will display an error message, explaining the reason for failure.
/**
* return an error handling callback function,
* actionscript closure is used
* @param {String} range
* @param {ArrayCollection} displayItemsResult
* @param {ItemList} itemList
* @param {Label} priceRange
* @return function
*/
private function onSomeItemsReturnedFailed(range: String, displayItemsResult:ArrayCollection, itemList: ItemList, priceRange: Label):Function {
return function(fault:FaultEvent):void {
var faultMessage:Fault = fault.fault;
errorMessage += ("Error: " + faultMessage.faultDetail + " in " + range + ". ");
resizeDisplayItems(range, displayItemsResult, itemList, priceRange, 0);
}
}
Implement the user interface according to your requirements. You can use any Flex UI components to implement your UI functions. For example, in this FindItemsAdvanced sample, we use the Label component to show the search title, we use the Customized ItemList component to show the items in a grid, we use the TextInput component to get the search input, and so on.
<mx:Style source="default.css" />
<mx:VBox width="800" height="100%">
<mx:Label text="Search Result For " id="searchResultFor" styleName="h1"/>
<mx:Label text="$0-$50 " id="priceRange1" styleName="h2"/>
<eBayUI:ItemList id="itemListOne" verticalScrollPolicy="off" dataProvider="{displayItemsResultOne}" rowCount="1" showBidColumn="false"/>
<mx:Label text="$51-$200 " id="priceRange2" styleName="h2"/>
<eBayUI:ItemList id="itemListTwo" verticalScrollPolicy="off" dataProvider="{displayItemsResultTwo}" rowCount="1" showBidColumn="false"/>
<mx:Label text="$201-$500 " id="priceRange3" styleName="h2" />
<eBayUI:ItemList id="itemListThree" verticalScrollPolicy="off" dataProvider="{displayItemsResultThree}" rowCount="1" showBidColumn="false"/>
<mx:Spacer height="20"/>
<mx:HBox width="100%">
<mx:Spacer width="25%"/>
<mx:Label text="Query Keyword : "/>
<mx:TextInput id="searchInput"/>
<mx:Button click="onSearchClick(event)" label="Go"/>
</mx:HBox>
<mx:Label text="{errorMessage}" bottom="25" left="10" styleName="h2"/>
</mx:VBox>
Also, you can use the design editor in Flex Builder 2 to design and create your user interface as required.
Now we are ready to create the main function for our Flex tutorial. This function will be called when your Flex application starts. It is like the "main" method in most object-oriented applications.
private function onApplicationComplete():void {
// if QueryKeywords was omitted from the web page, hard-code the sarch for "ipod"
queryKeywords = Application.application.parameters.QueryKeywords;
if (('' == queryKeywords) || (undefined == Application.application.parameters.QueryKeywords)) {
queryKeywords = "ipod";
}
searchResultFor.text = "Search Result For " + queryKeywords;
service = initEBayService();
// now that configurations are all set, search for the items
performSearch();
}
The onApplicationComplete() function calls the initeBayService function to validate the required credentials and to initialize the shopping service. The next section will provide further detail about required credentials and the initeBayService function.
The search button provided in the user interface of the FindItemsAdvancedSample is linked to the onSearchClick method. When a user clicks the search button, this method is called which then calls the "clear" method and the "performSearch" method.
/**
* search directly using the search box at the end
*/
private function onSearchClick(event:Event):void {
this.queryKeywords = searchInput.text;
searchResultFor.text = "Search Result For " + queryKeywords;
if(this.queryKeywords == null || this.queryKeywords == '') {
Alert.show("qeury keywords can not be empty, please input again!");
return;
} else {
clear();
performSearch();
}
}
private function clear():void {
errorMessage = "";
displayItemsResultOne.removeAll();
displayItemsResultTwo.removeAll();
displayItemsResultThree.removeAll();
}
Before we can connect to the web service, we need to create an instance of the Shopping class (with config parameters so we can access the eBay Shopping Web Service). In the FindItemsAdvanced sample the credential information is stored in the "sampleUtils" file. This file also defines a function called initEBayService that creates an instance of the shopping class.
// ActionScript file
import com.ebay.shoppingservice.*;
private function initEBayService():Shopping {
var apiAppName:String = null;
var trackingID:String = null;
var trackingPartnerCode:String = null;
var affiliateUserID:String = null;
var siteID:String = null;
var service:Shopping;
// Read parameters passed in by the HTML container using flashvars
apiAppName = Application.application.parameters.ebayAppId;
if (('' == apiAppName) || (undefined == Application.application.parameters.ebayAppId)) {
//replace your 'appId' here
//apiAppName = "<Your AppId>";
}
trackingID = Application.application.parameters.ebayTrackingID;
if (('' == trackingID) || (undefined == Application.application.parameters.trackingID)) {
//replace your 'trackingID' here
//trackingID = "<Your TackingID>";
}
trackingPartnerCode = Application.application.parameters.ebayTrackingPartnerCode;
if (('' == trackingPartnerCode) || (undefined == Application.application.parameters.ebayTrackingPartnerCode)) {
//replace your 'trackingPartnerCode' here
//trackingPartnerCode = "<Your TrackingPartnerCode>";
}
affiliateUserID = Application.application.parameters.ebayAffiliateUserID;
if (('' == affiliateUserID) || (undefined == Application.application.parameters.ebayAffiliateUserID)) {
//replace your 'affiliateUserID' here
//affiliateUserID = "<Your AffiliateUserID>";
}
siteID = Application.application.parameters.ebaySiteID;
if (('' == siteID) || (undefined == Application.application.parameters.ebaySiteID)) {
//replace your 'siteID' here
//siteID= "<Your SiteID>";
}
var props:Object = new Object();
props["appId"] = apiAppName;
props["trackingId"] = trackingID;
props["trackingPartnerCode"] = trackingPartnerCode;
props["affiliateUserId"] = affiliateUserID;
props["siteId"] = siteID;
// create a ShoppingService object (so you can call SDK functions
// like findItems, getItemStatus ...
service = new Shopping(props);
return service;
}
Before running the application, update the credential information. Enter your appId (mandatory), trackingId, and any other credentials where required in the sampleUtils.as file. Alternatively, you may pass in the credentials through the .html wrapper for your .swf file, we will explain this further in the 'Deploying the widget' section.
To run the application from within the Flex Builder 2 IDE, right click the FindItemsAdvanced.mxml file and select "run application". Then Flex Builder will compile the code, create the FindItemsAdvanced.swf file, and store it in the \bin folder of the project directory. Flex Builder will also create an .html wrapper around the FindItemsAdvanced.swf file and launch the application in your default web browser.
Use a text editor to create an .html file and then add tags within your .html file that point to the .swf file that will be used by your application. Below, we use the default .html wrapper (such as FindItemsAdvanced.html, auto-generated by Flex Builder 2) as an example. Note that you can alternately add this information to an existing .html file.
As mentioned above, you can pass your credentials to an .swf file through the html wrapper. You can include the credentials in the flashVars parameters. To ensure browser compatibility, you can add the flashVars parameters in three places. The first is as a parameter of a javascript function call. This example uses the javascript function, AC_FL_RunContent:
<script language="JavaScript"> ... AC_FL_RunContent( 'src', 'FindItemsAdvanced, ... 'flashVars','ebayAppId=YourAppId&QueryKeywords=ipod', ... ) ... </script>
The second and third flashVars parameters are added as a parameter element of an object .html tag, and a property of the embed .html tag (within an object tag):
<noscript> <object ...> <param name="movie" value="FindItemsAdvanced.swf" /> ... <param name="flashVars" value="ebayAppId=YourAppId&QueryKeywords=ipod" /> ... <embed src="FindItemsAdvanced.swf" ... flashVars="ebayAppId=YourAppId&QueryKeywords=ipod" ... /> ... </embed> </object> </noscript>
Congratulations! You now have a working application that uses eBay Shopping Web Services.
This section contains observations about the tutorial and offers some alternate ways to achieve similar or better results. We've also provided some suggestions about where you can go from here.
Now that you've completed the Tutorial for the FindItemsAdvanced call, you may want to proceed to a more complex tutorial. The GetUserProfile tutorial uses both the FindItemsAvanced call and the GetUserProfile call to create an application that returns both item data and user data.
The eBay Affiliate Program allows you to earn money by driving traffic to the eBay site using applications or widgets you create and post on your own web page. You can think of this as a way to enhance your existing business or create a new enterprise. With just a little effort, you can earn a lot of money.
Now that you have a working search application, you can earn money with the eBay Affiliate Program! Join the affiliate program now!
Once you have joined the eBay Affiliate Program, sign up for the Affiliate API Tier of the eBay Developers Program.
As noted at the beginning of the tutorial, we tried to keep things simple. The eBay community codebase contains many excellent samples that are more complex and many give you good ideas for ways to design your applications.
The sample provided with this tutorial was built and tested on a Windows 2003 Server platform using Adobe's Flex Builder 2 for Win32 and Microsoft IIS 5.0.
For the tutorial, we took a minimalist approach to input parameters. The GetUserProfile call is very powerful. It supports numerous input parameters, and the query supports AND/OR logic and wildcards. Visit the Flash Developer Center for links to documentation and additional information.
Here's a list of resources for the topics and technologies introduced in this tutorial:
In order to leave a comment in this section, you must view this Tutorial via the eBay web site: online version.
© 2008 eBay Inc. All rights reserved.
eBay and the eBay logo are registered trademarks of eBay Inc.
All other brands are the property of their respective owners.