One of the most common requests for the Flash team is to provide a Webservice component for Actionscript 3.0 like the one Flash has for Actionscript 2.0. Finally, Flash has provided the features in CS4 to allow users to use any Flex components that does not rely on Flex framework such as Flex WebService component and HTTPService.
In the below example am going to demonstrate how users can use Flex WebService in Flash to get countries names and populate them in a Flash DataGrid component.
1. File > New
2. Select "Flash File (Actionscript 3.0)".
3. Open the Component panel and drag a DataGrid component to the stage and call it "dg".
5. File > Publish settings and click on "Flash" tab.
6. Click on "Settings" button to launch "Advance Actionscript 3.0 Settings"
7. Click on the "library path" tab
8. Click on "Browse to SWC file" icon and get the "framwork.swc" and "rpc.swc" from the Flex SDK as follow :
You can download FlexSDK and select the above SWC's from the following location
"sdks/3.0.0/frameworks/libs/"
9. Open the action panel and import the following:
import mx.rpc.soap.*;
import mx.core.*;
import mx.rpc.events.*;
import fl.data.DataProvider;
10. The following 2 lines of code are required if you are using SDK 3.0.0 but not if you are using higher version of SDK
//The following 2 lines to register class for
//Interface"mx.interface::IResourceManager
var resourceManagerImpl:Object = ApplicationDomain.currentDomain.getDefinition("mx.resources::ResourceManagerImpl");
Singleton.registerClass("mx.resources::IResourceManager", Class(resourceManagerImpl));
11. Now copy the following and paste below the above 2 line of codes
var foo:WebService = new WebService();
foo.addEventListener("load", finishedLoading);
foo.loadWSDL("http://www.webservicex.net/country.asmx?WSDL");
var myOperation:Operation;
function finishedLoading(evt:LoadEvent):void
{
myOperation = Operation(foo.getOperation("GetCountries"));
myOperation.addEventListener("fault", wsdlFault);
myOperation.addEventListener("result", wsdlResult);
myOperation.send();
}
function wsdlFault(evt:FaultEvent):void
{
trace(evt.fault);
}
function wsdlResult(evt:ResultEvent):void
{
trace(evt.result);
var myResult:Object = evt.result;
var len:Number = myResult.length;
var xml:XML = XML(evt.result);
var dp:DataProvider = new DataProvider(xml);
dg.dataProvider = dp;
}
12. Test Movie and you should get a list of all the countries inside the datagrid :
Hi,
ReplyDeleteReally good information very helpful "Using Flex Webservice component in Flash CS4"
thanks
Hi,
ReplyDeleteit doesn't work fine for me.
Looks like the WS is never loaded.
function finishedLoading(evt:LoadEvent):void is never executed at runtime.
I used your example with http://www.webservicex.net/country.asmx?WSDL
What could happen ?
Same here..
ReplyDeleteThe function finishedLoading seems never to load...
Ne help??
I just tried it and worked for me. Would you please e-mail me your Fla and i will check it out for you.
ReplyDeleteThanks,
Tareq
treguess@gmail.com
I've created the example, nothing else in the file. When I hit "Test Movie," it takes an ungodly amount of time to compile...something like 40 seconds. I have a Dual G5 2.7 GHz PowerMac and am used to pretty speedy compiles. Am I to expect this when using Flex SWCs? Or any SWCs? It has to be those since I don't have anything else really going on in the file. For good measure I removed the DataGrid component but still had really long compiles. Anyone else having this issue?
ReplyDeleteThe performance issue you are seeing is because you are compiling against all the classes in the flex framework "Framework.swc". You won't see this problem with SWC's you create using Flex or Flash.
ReplyDeleteWhat is the trick to send parameters to the web service? I checked the Flex docs and it wasn't immediately apparant.
ReplyDeleteI have a the same question... how can we pass multiple parameters?
ReplyDeletemyOperation=Operation(ws.getOperation("GetWeatherByZipCode("+zip+")"));
When I test the movie, I get not a data grid, but a horrific flash of components. The error says "access of undefined property dg."
ReplyDeleteThe source being the line:
"dg.dataProvider= dp;"
Also, the web service used in the example no longer works... I changed the address to another and still got the same Seizure buttons response.
dg is the name of the datagrid instance on stage. You are getting the error because you did not give an instance name to the datagrid. what you need to do is select the datagrid on stage and give it a name as dg inside the Properties Inspector.
ReplyDeleteLet me know if you still have a problem and i will send you an FLA.
This really great! Thanks
ReplyDeleteit works for me...
ReplyDeletebut, I little confused, how to edit the data.. it's same with web service in as2 !?
can u give me an example code to change or edit the data !?
thanks before... ^^
Tareq,
ReplyDeleteThis is a very useful post. Coming from flex and trying to learn flash this is one of the most confusing areas for me. however, the flex framework is rather large and bloated, so should i use URLRequest obj instead of importing the framework.swc and using flex's HttpService? Thank you very much.
@Tomas You have to change: http://www.webservicex.net/country.asmx?WSDL
ReplyDelete... into: http://www.webservicex.com/country.asmx?WSDL
/Jonas | israelsson.nu
really informative post.
ReplyDeletebut can i use the flex httpservice instead of webservice?
Yes, you can use the httpservice in Flash too.
ReplyDeleteExcellent tutorial!
ReplyDelete"I think I am" and "polarfileio" asked how to pass parameters to a web services. The answer is to add it to the SEND operation as a parameter. E.g. the following query looks up the international dialing code for a country.
myOperation = Operation(foo.getOperation("GetISD"));
myOperation.send("France");
(NB: the web service being used by this tutorial seems to give duplicate answers. So you will get '33' back twice as the response to the above Operation. The above code isn't faulty!)
Hi Tareq,
ReplyDeleteThanks for such a great post about a very frustrating issue. I've got the same problem as @drukepple above with compiles taking ages. In response you said "you won't see this problem with SWC's you create using Flex or Flash."
I've done some Googling around for how this might be done but I'm still confused. Could you give me any help about how to do this from where you finish your tutorial above?
Thank you, James! Regarding the Web services example, this is the easiest way to use Flex Web service in Flash otherwise you would have to add every single class that being used and needed by the Flex web service component to your Flash source path and I really don't think that would even make it faster. What I meant by "SWC's you create using Flex or Flash" is those SWCs you generate for your custom classes.
ReplyDeleteThe performance problem that we are seeing here is because Flash is compiling against the whole Flex framework.
Hope that helps
tareq
I did all that is asked here, I downloaded the Flex_sdk_3 folder, but the path isn't the same. There is no 3.0.0 folder. I do find the specified swc files n the flex_sdk_3\frameworks\libs folder.
ReplyDeleteAfter failure, I copied and pasted code. Still doesn't work. Puzzlingly, I have no errors.
The tutorial seems great; I can follow the instructions. Unfortunately, I can't make it work. The trouble is, it is created by one who knows for others who know. It would be nice if one of those who make this would would explain what they did differently (from the instructions) to make it work.
Just imagine what Adobe would have if they could communicate this stuff!
Thomas
BTW, I don't mean to pick on you. I appreciate your effort. I realize it isn't your job to teach everyone about Flash. It just seems like there is so little information that is complete. It reminds me of the old books on Chess. It used to be impossible to find a book that could list the moves in the game without horrific mistakes. And I can't find much useful guidance on Flex.
ReplyDeleteI'm sure my excuse for a brain plays a part here.
Hey WhidbeyThomas; I'm guessing the problems you're experiencing come from getting the Flex SDK setup. I don't think I've ever downloaded a version of the SDK where it was just named "3.0.0" or whatever, nor is there a "sdks" directory by default on my computer.
ReplyDeleteI think an expanded version of what Tareq said in step 8 was...
Download the Flex SDK
Unzip it and place it somewhere on your hard drive where you'd like it to live
Click the target icon and browse to the sdk folder you just unzipped
From there, go into "frameworks/libs/" and select the "framework" and "rpc" SWCs.
If it's not just that (sounds like you did get that far), then unfortunately it's really hard to tell without actually looking at your file. "No errors" isn't much to go on. I'd be happy to take a look if you want to email it to me. I'm am on Google's mail service, with a username of drukepple. I hope you can figure out the actual address, and that spam crawlers cannot.
On another note; you're right that there is a certain level of knowledge assumed. However, as a college instructor I'm acutely aware of the balance one must walk while explaining something to the masses. You will have all sorts of backgrounds and skill levels in the same class, regardless of pre-requisites. I'm not trying to defend either Tareq, or you, as I can see both sides of the argument. On the one hand, you want to provide complete and accessible information. On the other hand, going too far towards "complete" means repeating the same information a lot of the time. Imagine if Tareq had already blogged about the steps necessary to hook up the Flex SDK so Flash CS4 knew where it was. It would be a waste of time to re-write that information just for this post, and it would have been a waste of time for "those who know" to have to read it. At the same time, it would have been nice to link to that article at the appropriate place so that "those who know" could just skip it, while giving the option for "those who don't know" to take a tangental trip so that they become one of "those who know."
For example. on my blog, I provide tips and techniques as well, a lot of them dealing with JSFL. Rather than repeat the mantra of how to install a JSFL command every time, I created a "how to" page and link to that if necessary. It saves me time, and once you "in the know," it saves you time, too. Assuming you read my blog.
Anyway, I hope all of this helps.
Hi WhidbeyTomas, Sorry if I was unclear on some of my steps, but I assumed that people who are interested in this subject would already know how to link Flash authoring to the Flex SDK. I guess i was wrong and should pay attention to this kind of stuff in my future blogs. Regarding your issue, just follow what drukepple described in his response and make sure that the Web Service itself works and not down by simply copying the web service link (http://www.webservicex.com/country.asmx?WSDL)and posting it in the browser address bar and then click enter; which should show xml representation of the web service itself if it's working. When i do that now i see "Server is Busy" message which could be why you are not getting any result.
ReplyDeleteLet me know if you want me to check out your Fla.
Thanks,
Tareq
Thanks to publish nice help blog
ReplyDeleteTareq, thanks for this. Amazing how little organiized information there is on something so important.
ReplyDeleteTo give back, the parameter question was not effectively solved above, because single params default and are easy. But here is a more complex input, output example, inspired by your site tand this guy doing SAP wsdl work:
http://blog.danmcweeney.com/57
Say we have wsdl that takes in three parameters, A, B, C with C being an array parameter....
and returns 2 items D, E
code looks like this:
--
var O:Object = new Object();
O.A = "a stuff";
O.B = "b stuff";
O.C = new Array("C1, C2");
myOperation.arguments = [O];
myOperation.send();
--
receiving:
trace(evt.result.D);
trace(evt.result.E);
--
The Dan Sweeney site also talks about in/out parameters.
Thanks again Man. Good Luck!
Typo above, :
ReplyDeleteO.C = new Array("C1", "C2");
I have create a flash movie with flex 3.3. I am trying to access my wsdl file, I am getting the following error
ReplyDeletehere1
[RPC Fault faultString="" faultCode="EncodingError" faultDetail="null"]
this is my flash code
import mx.rpc.soap.*;
import mx.core.*;
import mx.rpc.events.*;
import fl.data.DataProvider;
var foo:WebService = new WebService();
foo.addEventListener("load", finishedLoading);
foo.addEventListener("connect",connected);
//foo.loadWSDL("http://www.webservicex.com/country.asmx?WSDL");
foo.loadWSDL("http://rubiks.nimbus.info/testWSDL3/newWSDL3.wsdl");
var myOperation:Operation;
function finishedLoading(evt:LoadEvent):void
{
myOperation = Operation(foo.getOperation("getPlanet"));
myOperation.addEventListener("fault", wsdlFault);
myOperation.addEventListener("result", wsdlResult);
myOperation.send();
}
function wsdlFault(evt:FaultEvent):void
{trace("here1")
trace(evt.fault);}
function wsdlResult(evt:ResultEvent):void
{ trace("here2");
trace(evt.result);
var myResult:Object = evt.result ;
var len:Number = myResult.length;
trace(len);
var xml:XML = XML(evt.result);
var dp:DataProvider = new DataProvider(xml);
dg.dataProvider = dp;
}
Please give me some clue as I am new to this Flash programming.
Note: your example worked perfectly and displayed all the countries.
It seems to me that the issue you are describing is an SDK bug. I am going to confirm and get back to you.
ReplyDeleteThanks,
Tareq
Could you please send me the following :
ReplyDelete1. wsdl xml file.
2. soap response xml file.
thanks,
tareq
Hi All,
ReplyDeleteI just tried my example with Flex SDK 4 and got the following error :
1046: Type was not found or was not a compile-time constant: [flashx.textLayout.compose]::ITextLineCreator.
To solve this problem you will need to add
"textLayout.swc" to the library path in addition to framework.swc and rpc.swc.
it is located in the following location :
..\sdks\4.0.0\frameworks\libs\
Thanks,
tareq
Hi,
ReplyDeleteI've just emailed my code, I could'nt attach here as html blocks. I managed to connect to the wsdl but could'nt return any value from the function. it always return null.
Please check the code and let me know.
Thanks for your time and kind
Try this one~
ReplyDelete(mix article above and p647-650 of Actionscript 3.0 Cookbook)
//////////////////////////////////////
import mx.rpc.soap.*;
import mx.core.*;
import mx.rpc.events.*;
import fl.data.DataProvider;
var myWebService = new WebService();
myWebService.wsdl = "http://www.webservicex.net/country.asmx?WSDL";
myWebService.loadWSDL();
myWebService.addEventListener(LoadEvent.LOAD, loadDone);
myWebService.addEventListener(FaultEvent.FAULT, loadFault);
trace('hello?');
var myOperation:Operation;
function loadDone(evt:LoadEvent)
{
trace("done?");
myWebService.addEventListener(ResultEvent.RESULT, wsResult);
myWebService.addEventListener(FaultEvent.FAULT, wsError);
myWebService.GetCountries();
// myOperation=Operation(myWebService.getOperation("GetCountries"));
// myOperation.addEventListener("fault", wsError);
// myOperation.addEventListener("result", wsResult);
}
function loadFault(evt:FaultEvent)
{
trace('fault');
}
function wsError(evt:FaultEvent)
{
trace('something wrong!');
}
function wsResult(evt:ResultEvent)
{
var xml:XML = new XML(evt.result);
var dp:DataProvider = new DataProvider(xml);
MyDG.dataProvider = dp;
trace('something good!');
}
//
Any question : sseoyh7@snu.ac.kr
Or when you use DocumentClassDefinition with .as file, try this one :
ReplyDelete//////////////////////
package
{
import flash.display.Sprite;
import mx.rpc.soap.*;
import mx.core.*;
import mx.rpc.events.*;
import fl.data.DataProvider;
import fl.controls.DataGrid;
public class WebserviceAndFlashRemotingImplementation extends Sprite
{
var _myWebService;
public function WebserviceAndFlashRemotingImplementation()
{
_myWebService = new WebService();
_myWebService.wsdl = "http://www.webservicex.net/country.asmx?WSDL";
_myWebService.loadWSDL();
_myWebService.addEventListener(LoadEvent.LOAD, loadDone);
_myWebService.addEventListener(FaultEvent.FAULT, loadFault);
trace('hello?');
}
private function loadDone(evt:LoadEvent)
{
trace("done?");
_myWebService.addEventListener(ResultEvent.RESULT, wsResult);
_myWebService.addEventListener(FaultEvent.FAULT, wsError);
_myWebService.GetCountries();
// myOperation=Operation(myWebService.getOperation("GetCountries"));
// myOperation.addEventListener("fault", wsError);
// myOperation.addEventListener("result", wsResult);
}
private function loadFault(evt:FaultEvent)
{
trace('fault');
}
private function wsError(evt:FaultEvent)
{
trace('something wrong!');
}
private function wsResult(evt:ResultEvent)
{
var xml:XML = new XML(evt.result);
var dp:DataProvider = new DataProvider(xml);
var MyDG:DataGrid = new DataGrid();
MyDG.width = stage.stageWidth;
MyDG.height = stage.stageHeight;
MyDG.dataProvider = dp;
addChild(MyDG);
trace('something good!');
}
}
}
////
Any questions : sseoyh7@snu.ac.kr
And this is the same code except for error handling :
ReplyDelete///////////////
package
{
import flash.display.Sprite;
import mx.rpc.soap.*;
import mx.core.*;
import mx.rpc.events.*;
import mx.rpc.Fault;
import fl.data.DataProvider;
import fl.controls.DataGrid;
import flash.text.*;
public class WebserviceAndFlashRemotingImplementation extends Sprite
{
var _myWebService;
public function WebserviceAndFlashRemotingImplementation()
{
_myWebService = new WebService();
_myWebService.wsdl = "http://www.webservicex.net/country.asmx?WSDL";
_myWebService.loadWSDL();
_myWebService.addEventListener(LoadEvent.LOAD, loadDone);
_myWebService.addEventListener(FaultEvent.FAULT, loadFault);
trace('hello?');
}
private function loadDone(evt:LoadEvent)
{
trace("done?");
_myWebService.addEventListener(ResultEvent.RESULT, wsResult);
_myWebService.addEventListener(FaultEvent.FAULT, wsError);
_myWebService.GetCountries();
// myOperation=Operation(myWebService.getOperation("GetCountries"));
// myOperation.addEventListener("fault", wsError);
// myOperation.addEventListener("result", wsResult);
}
private function loadFault(evt:FaultEvent)
{
trace('fault');
var fault:Fault = evt.fault;
var message:String = "An error occurred.";// The details are as follows\ncode: " + fault.faultCode;
message+="\ndetail:"+fault;
var text:TextField = new TextField();
text.text = message;
text.autoSize = TextFieldAutoSize.LEFT;
addChild(text);
}
private function wsError(evt:FaultEvent)
{
trace('fault');
var fault:Fault = evt.fault;
var message:String = "An error occurred.";// The details are as follows\ncode: " + fault.faultCode;
message+="\ndetail:"+fault;
var text:TextField = new TextField();
text.text = message;
text.autoSize = TextFieldAutoSize.LEFT;
addChild(text);
}
private function wsResult(evt:ResultEvent)
{
var xml:XML = new XML(evt.result);
var dp:DataProvider = new DataProvider(xml);
var MyDG:DataGrid = new DataGrid();
MyDG.width = stage.stageWidth;
MyDG.height = stage.stageHeight;
MyDG.dataProvider = dp;
addChild(MyDG);
trace('something good!');
}
}
}
great post, but this just makes my swf size BIG "187 KB". Any way to bring it down?
ReplyDeleteJohn
Nice to know this is possible in Flash, but Im having problems getting it to work when I upload it to my server. I get an outline of the datagrid, but nothing else. This all works as it should when im running the swf locally.
ReplyDeleteAlso, for future reference, will this code work across a secure server?
Cheers
Ash
Hi there,
ReplyDeleteDoes anyone know why this doesn't work when I put it in a class of its own and then call it from my document class?
ie. I have a class called "WebServiceConnector", that doesn't connect when i import it into the document class, yet works when i set it as the document class.
any help?
cheers :-)
There is at least one comment here about how much the file size of your swf will be increased using this Flex SDK approach. In my case, I see a 5K swf increase to something like 342K which is a huge increase and an unacceptable solution for some cases.
ReplyDeleteI forgot to also add that the sheer compile time of the framework also makes this approach quite a test for you patience since every time you want to test your swf, you're faced with something like a minute of compilation time verses a typical few seconds.
ReplyDeleteOK, after more research, I have found what appears to be a better alternative to the Flex SDK approach. Please check out:
ReplyDeletehttp://www.wellconsidered.be/as3-webservice-component/
I tested this myself and it is working for me. And bonus, no huge swf file sizes or painful compile times. I only tested returning strings from my web service which works fine. Follow the references on the link to see what sort of open issues exist.
the wellconsidered package above does not appear to work out of the box with some wsdl recognition (it appearss very microsoft oriented).
ReplyDeleteHowever, with the source code available in it it does manage to make it pretty apparent on how to write your own just using http POST.
We have very simple and established wsdl calls, so they have been hard coded into a library and our compile times have been reduced by about 90%. Thanks for the hint.
I think it shows that the this technoilogy is still a bit immature and still needs to grow from a programming perspective. It seems very hard to get a word on as4? Anyone know?
UPDATE:
ReplyDeleteThe URL I listed in my post is no longer working:
(http://www.wellconsidered.be/as3-webservice-component/)
Instead, please use:
http://code.google.com/p/as3webservice/
with the as3webservice... is there anything that needs to be done on a hosted platform? any extra ports need to be opened?
ReplyDeleteAnyone else getting this error?
ReplyDelete"Variable ResourceManagerImpl is not defined"
REGARDING LONG COMPILE TIMES:
ReplyDeleteWanted to update this record that turning off warning messages _vastly_ decreases the compile time in CS4. So those unhappy with the long time should make sure they do this.
@anonymous, regarding turning off warnings:
ReplyDeleteBut I like warnings. Call me crazy, but I'm not turning them off just so I can use a Flex Webservice component. I doubt I'm the only one who feels that way.
Hey,
ReplyDeleteI did the same as you did here, but with HTTPService.
But I get the following Error:
"1046: Type was not found or was not a compile-time constant: ResultEvent."
That is starnge, because I selected the "rpc.swc".
And I wrote:
import mx.rpc.http.HTTPService;
import mx.rpc.FaultEvent;
import mx.rpc.ResultEvent;
It was a stupid mistake.
ReplyDeleteIt should be import mx.rpc.events.ResultEvent;
This is working for me when I run it locally, but once I run it on a webserver and browser, there's nothing populating the datagrid anymore. I thought it might be crossdomain.xml, but theirs is wide open. Help?
ReplyDeleteIn Flash you can get this to work with the URLLoader and URLRequest classes too. No need for Flex' HTTPService class.
ReplyDeleteFor an example check http://www.thetechlabs.com/tutorials/xml/learn-how-to-create-flash-components-using-actionscript-30-xml-and-flickr-api/
Hi Tareq, I need your Help: when I tested the movie in flash cs5,that worked perfectly, but when i Publish the movie, that´s don´t work. What is the problem??
ReplyDeleteHi, when i call any of your country.asmx?WSDL methods, like GetCountries, i get an error saying that there is no space on server hdd drive. Is there any option to fix it?
ReplyDeleteI have the following
ReplyDelete-
-
How can I initialise and send back the vars: StudentName, StudentScore, StudentLevel, StudentChar?
Also I have this:
-
-
How can I initialise StudentName and send it to my WSDL so it can check and send me back the results (I have it checked my db within the webservice so I want AS3 to return the fields attached to the found record).
This comment has been removed by the author.
ReplyDelete