In this tutorial, you will create a Flex Builder 2 application that searches the eBay site for a specific seller's feedback and available items, using both the FindItemsAdvanced and GetUserProfile calls.
Once you've completed a basic example with one call, such as the FindItemsAdvanced tutorial, you can expand your skills and your application's complexity. This tutorial shows how simple it is to use two calls together to create a useful application. The application allows a user to input a seller's ID to retrieve the seller's basic information and five of the seller's active listings which are ending soon. To do so, the application uses the GetUserProfile and FindItemsAdvanced Shopping API calls. When you complete this tutorial, you will have an application that looks like the following when it runs (for security reasons, user data is annonymized in following sample). You must run the sample with your appID and an eBay user ID, and you will see your information within the sample.

If the links you present to users (after making these calls) include affiliate tracking information, as described in this tutorial, you can earn money through the eBay Affiliate Program. For notes about the tutorial and the eBay Affiliate Program, see Notes and next steps.
This tutorial contains ten main steps:
Step 1: Create a Flex Builder 2 project file (.mxml file)
Step 4: Add the ActionScript functions for FindItemsAdvanced and GetUserProfile
Step 5: Add UI code to display the call results
Step 6: Create the "main" onApplicationComplete() method
Step 7: Review and modify the SampleUtils file
Step 9: Modify the .html file as needed
This tutorial was designed to explain the FindItemsAdvanced and GetUserProfile sample files, located within the /samples directory of your Flex/Flash SDK, and to help you create your own applications based on these samples. Some of the steps may only include a sub-set of the code that is actually in the sample. Please compare the tutorial to the samples as you proceed.
As previously mentioned, this is the second in a series of Tutorials about using the Flex/Flash SDK with Flex Builder 2. The first tutorial shows you how to build an application that uses the eBay Shopping API FindItemsAdvanced call. This tutorial builds on the knowledge you gained from the first tutorial and uses the GetUserProfile call as well as the FindItemsAdvanced call to return results about a specific seller.
Before you begin this tutorial, we recommend that you:
You need to create a project file (file with .mxml extension) before you can create the rest of your Flex application or widget. To create a blank .mxml file:
Note: The steps above are for creating a new Flex project, if you only want to run a sample project in the Flex/Flash SDK, then in step d, you only need to navigate to the folder for the sample you want to run (for example Samples/Flex/GetUserProfile).
At the beginning of your .mxml file, you need to import the packages for all of the eBay Flex/Flash SDK classes (and other Flex component classes) that you want to use in your widget. The following code contains the import statements that you need to include at the top of your .mxml file.
<mx:Script> import mx.collections.ArrayCollection; import com.ebay.shoppingservice.*; import mx.controls.Alert; import util.eBayUtil; import renderers.Link; import com.ebay.events.FaultEvent; import com.ebay.events.Fault </mx:Script>
You need to create variables to store data that your program will use when it runs. Some of these variables have a [Bindable] notation before the variable declaration, which means these variables can be bound to UI elements directly. Whenever these bound variables change, the corresponding UI elements will update automatically.
private var service:Shopping;
/**
* if severice call is failed
* @type Boolean
*/
private var hasError : Boolean = false;
Create an errorMessage variable.
(You can bind the errorMessage variable to a UI element directly.)/** * error message * @type String */ [Bindable] private var errorMessage:String = '';
Create variables for the rest of the data that your application or widget will use:
/** * seller id * @type String */ [Bindable] private var userID:String;
/** * seller's top 5 items * @type ArrayCollection */ [Bindable] private var sellerItems:ArrayCollection = new ArrayCollection();
/** * seller's url which links to seller's information at ebay.com * @type String */ [Bindable] private var seeAllURL:String;
/** * seller's title: seller id and link to seller's My World * @type Link */ [Bindable] private var title: Link = null;
/** * seller's image URL * @type String */ [Bindable] private var imageURL:String = null;
/** * seller's specification: feedback information * @type ArrayCollection */ [Bindable] private var specs: ArrayCollection = new ArrayCollection();
The FindItemsAdvanced and GetUserProfile Request and Response functions are complex functions within the example .mxml file in your SDK. You can use sections of the samples within your own code or you can modify them for your own purposes.
For this tutorial, we are going to break the call creation into three steps:
We will break the call request into small sections, so you can see what each section does.
* search seller by user id, call FindItemsAdvanced to get seller's top 5 items
*/
private function performSearch():void {
hasError = false;
Let's look at the ActionScript libraries to see how the GetUserProfileRequestType is instantiated.
Our sample below shows the GetUserProfileRequestType object creation in orange. The object is stored as the fiRequest:GetUserProfileRequestType variable.
// new GetUserProfileRequestType
// IncludeSelector is Details,FeedbackHistory, inlcude feedback history and details.
var fiRequest:GetUserProfileRequestType = new GetUserProfileRequestType({
userID: userID,
includeSelector: "Details,FeedbackHistory"});
The ActionScript library shows a similar constructor pattern for the FindItemsAdvancdedRequestType.

Our sample below shows the FindItemsAdvancedRequestType object creation in orange. The object is stored as the request:FindItemsAdvancedRequestType variable.
// new FindItemsAdvancedRequestType
// itemSort is EndTime ,sort by endtime.
// itemType is AllItemTypes, return all types
// maxEntries is 5, top 5 items
var request:FindItemsAdvancedRequestType = new FindItemsAdvancedRequestType({
sellerID: userID,
itemSort: SimpleItemSortCodeType.EndTime,
itemType: ItemTypeCodeType.AllItemTypes,
maxEntries: 5});
For each of the calls in the Flex/Flash SDK, you need to include success and failure callback functions. The success callback function will be called if the service call is successful, and the failure callback function will be called if the service call fails.
Add the success and failure callback functions for both GetUserProfile and FindItemsAdvanced.
The service call takes two parameters - one request object and one callback object (ShoppingCallback). The ShoppingCallback object wraps both the success and failure callback functions.
In the .mxml file that is included in the GetUserProfile sample, the service call function for GetUserProfile is included right after the GetUserProfileRequestType instantiation.
// service call function // getUserProfile is the name of the callback function for a successful GetUserProfile request // getUserProfileFailed is the name of the callback function for a failed GetUserProfile request service.getUserProfile(fiRequest,new ShoppingCallback(getUserProfile, getUserProfileFailed));
The success and failure behavior for the GetUserProfile call is defined in the .mxml sample as follows:
/**
* callback function when the GetUserProfile call fails
* display error message and clear previous user profile.
* @param {mx.rpc.events.FaultEvent}
*/
private function getUserProfileFailed(fault:FaultEvent):void {
hasError = true;
var faultMessage:Fault = fault.fault;
errorMessage = errorMessage + " " + faultMessage.faultDetail;
specs.removeAll();
title = createLinkObject("","","");
imageURL = null;
}
/**
* callback function when the GetUserProfile call succeeds
* display user profile
* @param {com.ebay.shoppingservice.GetUserProfileResponseType}
*/
private function getUserProfile(data:GetUserProfileResponseType):void {
if(data.ack.value != AckCodeType.Success.value) {
return ;
}
if (!hasError ) {
errorMessage = "";
}
if (data.user == null) {
specs.removeAll();
title = createLinkObject("","","");
imageURL = null;
} else {
convertData4ProfileUI(data);
}
seeAllURL = getSellerItemsURL(data);
}
In the .mxml file that is included in the GetUserProfile sample, the service call function for FindItemsAdvanced is included right after the FindItemsAdvancedRequestType instantiation.
// service call function // onSomeItemsReturned is the name of the callback function for a successful FindItemsAdvanced call // onSomeItemsReturnedFailed is the name of the callback function for a failed FindItemsAdvanced call service.findItemsAdvanced(request,new ShoppingCallback(onSomeItemsReturned, onSomeItemsReturnedFailed));
The success and failure behavior for the FindItemsAdvanced call is defined in the .mxml sample as follows:
/**
* callback function when the FindItemsAdvanced call fails
* display error message and clear previous items.
* @param {mx.rpc.events.FaultEvent}
*/
private function onSomeItemsReturnedFailed(fault:FaultEvent):void {
hasError = true;
var faultMessage:Fault = fault.fault;
errorMessage = errorMessage + " " + faultMessage.faultDetail;
sellerItems.removeAll();
itemList.rowCount = 1;
itemList.height = 50;
}
/**
* callback function when the FindItemsAdvanced call succeeds
* display items
* @param {com.ebay.shoppingservice.FindItemsAdvancedResponseType}
*/
private function onSomeItemsReturned(data:FindItemsAdvancedResponseType):void {
if(data.ack.value != AckCodeType.Success.value) {
return;
}
if (!hasError ) {
errorMessage = "";
}
if (0 == data.totalItems) {
sellerItems.removeAll();
itemList.rowCount = 1;
itemList.height = 50;
} else {
sellerItems = new ArrayCollection(convertData4ItemListUI(data));
itemList.height = 30 + sellerItems.length * 75;
itemList.rowCount = sellerItems.length;
}
}
Remember the variables that we set up at the beginning of this tutorial? Now we are going to store the returned data into those variables, since they will be bound to UI elements. Thus, whenever one of the values for a variable changes, the UI display of that data will also get updated.
The following code snippet gets item URLs that are returned with the response for the GetUserProfile call:
/**
* get seller item urls which link to eBay.com
* @param {com.ebay.shoppingservice.GetUserProfileResponseType}
* @return {String} seller item urls
*/
private function getSellerItemsURL(data: GetUserProfileResponseType): String {
var url:String = data.user.sellerItemsURL;
if (url != null) {
return url.replace(/&/g,"&");
}
return "";
}
The following code snippet stores data returned with the response for the GetUserProfile call:
/**
* set data required by profileUI. This data is from GetUserProfileResponseType
* @param {com.ebay.shoppingservice.GetUserProfileResponseType}
*/
private function convertData4ProfileUI(data:GetUserProfileResponseType): void {
var profile:Object = new Object();
var user:SimpleUserType = data.user as SimpleUserType;
if (user.myWorldSmallImage) {
this.imageURL = user.myWorldSmallImage;
}
var title:Link = createLinkObject("", "Seller: " + user.userID,user.myWorldURL);
this.title = title;
var specs:Array = new Array();
var i:int = 0;
var nameValue:Object = null;
var score:int = user.feedbackScore;
var scoreValue:Object = null;
if (data.feedbackHistory) {
score = data.feedbackHistory.uniqueNegativeFeedbackCount + data.feedbackHistory.uniquePositiveFeedbackCount;
nameValue = createLinkObject("Feedback Count: ",score + "",user.feedbackDetailsURL);
specs.push(nameValue);
nameValue = createLinkObject("Positive Feedback Percentage: ",
(data.feedbackHistory.uniquePositiveFeedbackCount/score* 100.0).toFixed(2) + '%' + "",null);
specs.push(nameValue);
} else {
nameValue = createLinkObject("Feedback Count: ",score + "",user.feedbackDetailsURL);
specs.push(nameValue);
}
nameValue = new Object();
nameValue = createLinkObject("Member Since: ",eBayUtil.toDateString(user.registrationDate),null);
specs.push(nameValue);
if (user.storeName) {
nameValue = new Object();
nameValue = createLinkObject("Store Name: ",user.storeName,user.storeURL);
specs.push(nameValue);
}
this.specs = new ArrayCollection(specs);
}
The following code snippet is a utility that creates the link object:
/**
* create link object, Key: URL
* @param {String} key: label
* @param {String} value: url title
* @param {String} url: url
* @return {Link} link object
*/
private function createLinkObject(key:String, value:String, url:String) : Link {
return new Link(key, value, url);
}
The following code snippet stores data returned with the response for the FindItemsAdvanced call:
/**
* Get top 5 items
* @param {com.ebay.shoppingservice.FindItemsAdvancedResponseType}
* @return {Array} items
*/
private function convertData4ItemListUI(data:FindItemsAdvancedResponseType): Array {
if (data.searchResult) {
var itemArray:SimpleItemArrayType = data.searchResult[0].itemArray;
var count:int = itemArray.item.length > 5? 5: itemArray.item.length;
var items:Array = new Array(count);
for (var i:int = 0; i< count; ++i) {
items[i] = itemArray.item[i];
}
return items;
}
return new Array();
}
Implement the user interface.
According to your requirements, you can use any Flex UI components to implement your UI functions. In the .mxml sample for GetUserProfile, for example, we use the Label component to show the widget title, a customized Profile component to show the seller's profile, and a customized ItemList component to show the seller's top 5 ending soon items. Some variables, like imageURL and sellerItems, are bound to UI elements directly.
<mx:Style source="default.css" />
<mx:VBox x="10" y="10" width="800" height="100%">
<mx:Label text= "Items for Sale by Seller {userID}" styleName="h1"/>
<eBayUI:Profile id="productProfile" imageURL="{imageURL}" title="{title}" specs="{specs}"/>
<mx:Label text="Top 5 Listings Ending Soon:" styleName="h2"/>
<eBayUI:ItemList id="itemList" dataProvider="{sellerItems}" rowCount="1" showBidColumn="true"/>
<mx:LinkButton id="seeAllLink" click="navigateToURL(new URLRequest(seeAllURL))" label="See All Items for this Seller" styleName="itemLink"/>
<mx:HBox width="100%">
<mx:Spacer width="25%"/>
<mx:Label text="User ID : "/>
<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>
The mx code in the example above can be created using the 'drag and drop' components in the Design tab of the Flex Builder IDE.
You can use the Design editor to bind objects to controls and create many different types of displays. And once you have created a display that you like, you can use it within other ActionScript 3 applications and widgets.
Create an onApplicationComplete function. This function will be called when your Flex application starts. It is like the "main method" in most object-oriented applications.
Note: The GetUserProfile sample needs to have a pre-set userID. You can set it in this function, or set it later in the .html wrapper using flashVars .
/**
* This function which is invoked on application complete
* It initializes the ebay Shopping Service, and calls the service API (getUserProfile)
*/
private function onApplicationComplete():void {
// get userId from index.template.html file
userID = Application.application.parameters.userID;
if (('' == userID) || (undefined == Application.application.parameters.userID)) {
//replace your 'UserID' here
//userID = "";
}
// init shopping service
service = initEBayService();
// do search
performSearch();
}
Next, add the function that defines the behavior of the click event for the Go button (next to the Search field). The Search field at the bottom of the widget can be used to search for any seller by userID.:
/**
* function which is invoked on clicking the 'Go' button next to the search field
* search user by user id
*/
private function onSearchClick(event:Event):void {
this.userID = searchInput.text;
if(this.userID == null || this.userID == '') {
Alert.show("User ID can not be empty, please input again!");
return;
} else {
performSearch();
}
}
The Flex/Flash SDK 2.2 includes a utility file where you can add your eBay parameters, such as you appID (required), siteID (optional), affiliate ID (if you are part of the affiliate program), and tracking information (optional). Note that the samples provided with the SDKs will not run unless you add your application ID.
// 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 = "";
}
trackingID = Application.application.parameters.ebayTrackingID;
if (('' == trackingID) || (undefined == Application.application.parameters.trackingID)) {
//replace your 'trackingID' here
//trackingID = "";
}
trackingPartnerCode = Application.application.parameters.ebayTrackingPartnerCode;
if (('' == trackingPartnerCode) || (undefined == Application.application.parameters.ebayTrackingPartnerCode)) {
//replace your 'trackingPartnerCode' here
//trackingPartnerCode = "";
}
affiliateUserID = Application.application.parameters.ebayAffiliateUserID;
if (('' == affiliateUserID) || (undefined == Application.application.parameters.ebayAffiliateUserID)) {
//replace your 'affiliateUserID' here
//affiliateUserID = "";
}
siteID = Application.application.parameters.ebaySiteID;
if (('' == siteID) || (undefined == Application.application.parameters.ebaySiteID)) {
//replace your 'siteID' here
//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;
}
Highlight your .mxml file in the Navigator window and then choose the Run option (click the white arrow within the green circle). This will build the project and create an .html file for your application.
Every time you select the Run command (or Build and Run) within Flex Builder 2, an .swf file and an .html file are created or updated. The .swf file is a compiled version of your project code and the Flex/Flash SDK (WDKASLib.swc) code, that you can run in Adobe's Flash Player 9.
Below, we use the default .html wrapper (auto-generated by Flex Builder 2) as an example:
<!-- saved from url=(0014)about:internet -->
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<script src="AC_OETags.js" language="javascript"></script>
<style>
body { margin: 0px; overflow:hidden }
</style>
<script language="JavaScript" type="text/javascript">
<!--
// -----------------------------------------------------------------------------
// Globals
// Major version of Flash required
var requiredMajorVersion = 9;
// Minor version of Flash required
var requiredMinorVersion = 0;
// Minor version of Flash required
var requiredRevision = 0;
// -----------------------------------------------------------------------------
// -->
</script>
</head>
<body scroll="no">
<script language="JavaScript" type="text/javascript" src="history.js"></script>
<script language="JavaScript" type="text/javascript">
<!--
// Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)
var hasProductInstall = DetectFlashVer(6, 0, 65);
// Version check based upon the values defined in globals
var hasRequestedVersion = DetectFlashVer(requiredMajorVersion, requiredMinorVersion, requiredRevision);
// Check to see if a player with Flash Product Install is available and the version does not meet the requirements for playback
if ( hasProductInstall && !hasRequestedVersion ) {
// MMdoctitle is the stored document.title value used by the installation process to close the window that started the process
// This is necessary in order to close browser windows that are still utilizing the older version of the player after installation has completed
// DO NOT MODIFY THE FOLLOWING FOUR LINES
// Location visited after installation is complete if installation is required
var MMPlayerType = (isIE == true) ? "ActiveX" : "PlugIn";
var MMredirectURL = window.location;
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
var MMdoctitle = document.title;
AC_FL_RunContent(
"src", "playerProductInstall",
"FlashVars", "MMredirectURL="+MMredirectURL+'&MMplayerType='+MMPlayerType+'&MMdoctitle='+MMdoctitle+"",
"width", "850",
"height", "100%",
"align", "middle",
"id", "main",
"quality", "high",
"bgcolor", "#869ca7",
"name", "main",
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else if (hasRequestedVersion) {
// if we've detected an acceptable version
// embed the Flash Content SWF when all tests are passed
AC_FL_RunContent(
"src", "main",
"width", "850",
"height", "100%",
"align", "middle",
"id", "main",
"quality", "high",
"bgcolor", "#869ca7",
"name", "main",
"flashvars",'historyUrl=history.htm%3F&lconid=' + lc_id + '',
"allowScriptAccess","sameDomain",
"type", "application/x-shockwave-flash",
"pluginspage", "http://www.adobe.com/go/getflashplayer"
);
} else { // flash is too old or we can't detect the plugin
var alternateContent = 'Alternate HTML content should be placed here. '
+ 'This content requires the Adobe Flash Player. '
+ '<a href=http://www.adobe.com/go/getflash/>Get Flash</a>';
document.write(alternateContent); // insert non-flash content
}
// -->
</script>
<noscript>
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
id="main" width="850" height="100%"
codebase="http://fpdownload.macromedia.com/get/flashplayer/current/swflash.cab">
<param name="movie" value="main.swf" />
<param name="quality" value="high" />
<param name="bgcolor" value="#869ca7" />
<param name="allowScriptAccess" value="sameDomain" />
<embed src="main.swf" quality="high" bgcolor="#869ca7"
width="850" height="100%" name="main" align="middle"
play="true"
loop="false"
quality="high"
allowScriptAccess="sameDomain"
type="application/x-shockwave-flash"
pluginspage="http://www.adobe.com/go/getflashplayer">
</embed>
</object>
</noscript>
<iframe name="_history" src="history.htm" frameborder="0" scrolling="no" width="22" height="0"></iframe>
</body>
</html>
There are two ways that you can deploy your completed ActionScript widgets:
With either of these methods, you need to point to the location of the widget by adding a source tag to your .html page that contains the location of your widget.
If you don't provide pre-configured parameters within the SampleUtils.as file and in the onApplicationComplete function (mentioned above), you (or your users) can add some flashVars parameters to the .html page (which points to your .swf file). These parameters include your Application ID and any other eBay parameters for your calls. (For the GetUserProfile call, we also need to provide the the userID.)
To ensure browser compatibility, you can add the flashVars parameters in three places:
<script language="javascript">
...
AC_FL_RunContent(
...
'flashVars', 'ebayAppId=YourAppId&userID=YourUserID',
...
)
...
</script>
<noscript>
<object ... >
...
<param name="flashVars" value="ebayAppId=YourAppId&userID=YourUserID" />
...
<embed ... flashVars="ebayAppId=YourAppId&userID=YourUserID" ... />
...
</object>
</noscript>
To deploy your project as a Flash Player application, put your compiled .swf file on a shared network drive or on the web where users with Flash Players can access it.
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 results. We've also provided some suggestions about where you can go from here.
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 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.