Flash AS3 Call a WSDL in a for loop - actionscript-3

I'm using the Flex SOAP web service, connecting to our WSDL and everything is dandy. However, I'm new to web services and the web guy is on holiday, so I'm a bit confused. The first thing I'm doing is running a check connection:
private function configXMLHandler(event:LoaderEvent):void {
fws.wsdl = checkWSDL;
fws.loadWSDL();
fws.addEventListener(LoadEvent.LOAD, wsdlLoaded);
}
private function wsdlLoaded(event:LoadEvent):void {
checkAbstract = fws.getOperation("retrieveAssetIdbyLabel");
checkAbstract.arguments = ["poll-asset-do-not-remove"];
var token:AsyncToken = checkAbstract.send();
token.addResponder(new Responder(checkAbstractResult, checkAbstractError));
}
private function checkAbstractError(event:FaultEvent):void {
trace('Error in the WSDL');
}
private function checkAbstractResult(event:ResultEvent):void {
if (event.result.returnCode == 0) {
trace('Web service check ok');
initContentLoader();
} else {
trace('Error in the WSDL');
)
}
}
This works fine, I get the result I expect, and so I move on. I then need to iterate through an XML list and call the same web service function for each asset in that XML, my thinking was to use a loop:
private function initContent(event:LoaderEvent):void {
assetList = event.target.content.asset;
for (var i:int = 0; i < assetList.length(); i++) {
assetAbstract = fws.getOperation("retrieveAssetIdbyLabel");
assetAbstract.arguments = [assetList[i + assetCount].assetLabel]; //get the current index in the xmllist + the assetCount, grab the corresponding assetLabel from the XML and pass that to the web service
trace(assetAbstract.arguments);
var assetToken:AsyncToken = assetAbstract.send();
assetToken.addResponder(new Responder(getAssetResult, getAssetError));
}
}
private function getAssetResult(event:ResultEvent):void {
var treasuresAsset:TreasuresAsset = new TreasuresAsset(event.result.returnCode, assetList[assetCount].asset.assetLabel, assetList[assetCount].asset.assetImage, assetList[assetCount].asset.assetDescription);
addChild(treasuresAsset);
assetCount++; //increase the asset count
}
private function getAssetError(event:FaultEvent):void {
trace(event.fault);
trace('An error occured when we tried to get an asset id in the loop');
}
I now get an error:
Error opening URL 'http://www.nhm.ac.uk/web-services/VisitorService/'
SOAPFault (Server): org.apache.axis2.databinding.ADBException: Unexpected subelement RetrieveAssetIdbyLabel
My immediate thought was that I need to create a new instance of the web service for each asset in the xml, and repeat my first code over and over. Can I use the web service only once, do you need to recreate the entire procedure?
Thanks.

OK, so I figured this out, and it was a simple XML namespace issue.
I replaced:
assetAbstract.arguments = [assetList[i + assetCount].assetLabel];
With:
var sender:String = assetList[i + assetCount].assetLabel;
assetAbstract.arguments = [sender];
And all is working.

Related

I need to ping a website with ActionScript or Animate

I had found this code ( I need to ping to an network with flash or actionscript )
Im not sure i understand it or how to use it exactly - I need for this to redirect to another frame if it worked and another if it failed
Is anyone able to help?
var ldr:URLLoader = new URLLoader();
ldr.addEventListener(HTTPStatusEvent.HTTP_STATUS, ldrStatus);
var url:String = "URL-TO-SITE";
var limit:int = 10;
var time_start:Number;
var time_stop:Number;
var times:int;
ping();
function ping():void
{
trace("pinging", url);
times = 0;
doThePing();
}
function doThePing():void
{
time_start = getTimer();
ldr.load(new URLRequest(url));
}
function ldrStatus(evt:*):void
{
if(evt.status == 200)
{
time_stop = getTimer();
trace("got response in", time_stop - time_start, "ms");
}
times++;
if(times < limit) doThePing();
}
Well it is trying to load a website 10 times and check the response. I would get rid of the limit though, it make no sense to try it 10 times in a row.
Don't forget that you will need a crossdomain.xml file on your server to be able to access it from flash.
You will need to add some more things for your purpose:
// add an event listener for a failed call
ldr.addEventListener(IOErrorEvent.IO_ERROR, ldrFailed);
ldr.addEventListener(SecurityErrorEvent.SECURITY_ERROR , ldrSecurityError);
function ldrFailed(evt:*):void
{
// loader failed (no internet connection), try to ping again
doFailedRedirect();
}
function ldrSecurityError(evt:*):void
{
// There is an internet connection but probably something is wrong with your crossdomain.xml
doFailedRedirect();
}
function doRedirect():void
{
// make your redirect here
}
function doFailedRedirect():void
{
// something went wrong, do your failed redirect here
}
Adjust the ldrStatus function:
function ldrStatus(evt:*):void
{
if(evt.status == 200)
{
// server responded with status 200 wich means everything is fine
time_stop = getTimer();
trace("got response in", time_stop - time_start, "ms");
doRedirect();
}
else
{
// there is an internet connection but the server returns something else (probably something is wrong with the server)
doFailedRedirect();
}
}

Why is my WinRT app closing when trying to debug my background task?

I am trying to experiment with downloading files on a regular basis with background tasks for windows store applications, and am having trouble.
I followed the sample at https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh977055.aspx, and even downloaded/ran it and everything worked perfectly (including being able to step into the timer background task).
So with that I created my own background task in a brand new Windows namespace
Win8BackgroundTest
{
public class TestBackgroundTask
{
public async void Run(IBackgroundTaskInstance taskInstance)
{
var deferral = taskInstance.GetDeferral();
var uri = new Uri("http://download.blender.org/peach/bigbuckbunny_movies/big_buck_bunny_480p_h264.mov");
var folder = ApplicationData.Current.LocalFolder;
var downloadFile = await folder.CreateFileAsync(uri.Segments.Last(), CreationCollisionOption.GenerateUniqueName);
var dataFile = await folder.CreateFileAsync("downloadData", CreationCollisionOption.GenerateUniqueName);
var downloader = new BackgroundDownloader();
var operation = downloader.CreateDownload(uri, downloadFile);
await FileIO.WriteTextAsync(dataFile, "Success at " + DateTime.Now);
deferral.Complete();
}
public static async void RegisterTask()
{
const string taskName = "TestBackgroundTask";
try
{
var status = await BackgroundExecutionManager.RequestAccessAsync();
if (status == BackgroundAccessStatus.Denied)
{
return;
}
}
catch
{
// already accepted
}
var tasks = BackgroundTaskRegistration.AllTasks
.Where(x => x.Value.Name == taskName)
.ToArray();
if (tasks.Any())
{
return;
}
var builder = new BackgroundTaskBuilder
{
Name = taskName,
TaskEntryPoint = "Win8BackgroundTest.TestBackgroundTask",
};
builder.SetTrigger(new TimeTrigger(60, false));
var registeredTask = builder.Register();
}
}
}
I set up the application's manifest with a Background Tasks declaration, checking the Timer properties checkbox, and set the EntryPoint to Win8BackgroundTest.TestBackgroundTask.
I then added the following at the end of my App.xaml.cs's OnLaunched() method:
TestBackgroundTask.RegisterTask();
Stepping through seems to have task registration work successfully with no exceptions. I then go back to visual studio, added a breakpoint to the first line in my task's Run() method, I then go to the debug locations toolbar, click the down arrow and select TestBackgroundTask. A few seconds later visual studio exits (as does my app).
Does anyone see what I am doing wrong that is causing background tasks to fail?
So after much frustration and a lot of trial and error the issue was a combination of both of the comments.
So first of all, it appears like you cannot have a background task in the same project as the rest of your windows store application. It must be in it's own windows runtime component project.
Finally, there are times where it just doesn't work and for whatever reason deleting the bin and obj folders fix it.

How do I use this URLRequest script?

I started learning ActionScript 3 a week ago and have stumbled across a huge learning curve. I found this script on the internet:
var _loader:URLLoader;
var _request:URLRequest;
function loadData():void {
_loader = new URLLoader();
_request = new URLRequest("http://www.travoid.com/game/Purchase.php?gid=1");
_request.method = URLRequestMethod.POST;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.addEventListener(IOErrorEvent.IO_ERROR, onDataFailedToLoad);
_loader.addEventListener(IOErrorEvent.NETWORK_ERROR, onDataFailedToLoad);
_loader.addEventListener(IOErrorEvent.VERIFY_ERROR, onDataFailedToLoad);
_loader.addEventListener(IOErrorEvent.DISK_ERROR, onDataFailedToLoad);
_loader.load(_request);
}
function onLoadData(e:Event):void {
trace("onLoadData",e.target.data);
}
function onDataFailedToLoad(e:IOErrorEvent):void {
trace("onDataFailedToLoad:",e.text);
}
This all seems to work and is generating no errors or output, however my issue comes about when I use this next part of code (which I made)
function vpBuy(e:MouseEvent):void{
loadData();
if (e.target.data == "false") {
inf_a.visible = true;
inf_b.visible = true;
inf_c.visible = true;
inf_d.visible = true;
btn_ok.visible = true;
}
}
I get this error:
ReferenceError: Error #1069: Property data not found on
flash.display.SimpleButton and there is no default value. at
travoid_fla::MainTimeline/vpBuy() onLoadData
The part that is probably throwing this is:
if (e.target.data == "false") {
I was hoping e.target.data was what stored the value on the web page (which displays as false) but apparently not. With the code I found on the internet, what stores the information on the web page?
Thanks,
Ethan Webster.
The URLLoader load method is asynchronous, you have to wait the server response before triyng to get the result.
The functions onLoadData and onDataFailedToLoad are there to do that. When the response is well received the function onLoadData is called and you can get the data in e.target.data or _loader.data
The error in your function vpBuy is you try to access the data property on the object that triggered the MouseEvent (maybe a Button) and that object don't have such variable.
Try the following:
/** button clicked load the datas from the server **/
function vpBuy(e:MouseEvent):void
{
// load the datas from the server
loadData();
}
/** the datas are well loaded i can access them **/
function onLoadData(e:Event):void
{
trace("onLoadData",e.target.data);
if( e.target.data == "false" )
{
inf_a.visible = true;
inf_b.visible = true;
inf_c.visible = true;
inf_d.visible = true;
btn_ok.visible = true;
}
}
Hope this could help you :)

Adobe Air and Dropbox

I'm trying to integrate dropbox into my BB Playbook app using adobe air in flashbuilder 4.6. I got the API from http://code.google.com/p/dropbox-as3/wiki/EXAMPLES and I'm also using that example.
public function getRequestToken():void
{
dropAPI.requestToken();
var handler:Function = function (evt:DropboxEvent):void
{
dropAPI.removeEventListener(DropboxEvent.REQUEST_TOKEN_RESULT, handler);
var obj:Object = evt.resultObject;
reqTokenKeyLabel.text = obj.key;
reqTokenSecretLabel.text = obj.secret;
// goto authorization web page to authorize, after that, call get access token
if (oauthRadioBtn.selected) {
Alert.show(dropAPI.authorizationUrl);
}
};
dropAPI.addEventListener(DropboxEvent.REQUEST_TOKEN_RESULT, handler);
if (!dropAPI.hasEventListener(DropboxEvent.REQUEST_TOKEN_FAULT)) {
dropAPI.addEventListener(DropboxEvent.REQUEST_TOKEN_FAULT, faultHandler);
}
}
This executes as expected but I don't know how to go further, I tried sending the user to the link generated and I allow the application but the get access token still fails. I feel like there is missing code, how does my application know what the access token is? should I not be getting something back from dropbox when the user allows the application?
Once the user has accepted the app in the web browser you should call this function in order to get the access token and secret:
public function getAccessToken():void{
dropAPI.accessToken();
var handler:Function = function (evt:DropboxEvent):void{
dropAPI.removeEventListener(DropboxEvent.ACCESS_TOKEN_RESULT, handler);
var obj:Object = evt.resultObject;
myAccessToken = obj.key;
myAccessSecret = obj.secret;
};
dropAPI.addEventListener(DropboxEvent.ACCESS_TOKEN_RESULT, handler);
if (!dropAPI.hasEventListener(DropboxEvent.ACCESS_TOKEN_FAULT)) {
dropAPI.addEventListener(DropboxEvent.ACCESS_TOKEN_FAULT, faultHandler);
}
}
Once you have them you can save them for future use. After that you have establish connection with Dropbox.
I hope this will help you

Error #2032: Stream Error. while calling webservices through an ssl connection

I'm trying to access a webservice with an SSL connection from an AIR application, I can access the webservice and retrieve the data without SSL, but when I try and access it through it I end up getting the 2032 Stream Error. As if what I was attempting to access wasn't available (which in fact it is, since I can easilly access it through my browsers).
I am doing the following:
private var server:String = "";
private var contentType:String = "";
private var method:String = "";
private var connector:connectionTest = null;
private var serverURL:URLLoader = new URLLoader();
public function Connector(a2:String, a3:String, mainClass:connectionTest)
{
server = "url";
contentType = a2;
method = a3;
connector = mainClass;
}
public function callService(callback:String, request:Object):void{
var url:URLRequest = new URLRequest(server);
var encoder2:JSONEncoder = new JSONEncoder(request);
var requestedString:String = "0" + encoder2.getString();
url.contentType = contentType;
url.method = method;
url.data = "callback=" + callback;
url.data +="&request=" + encodeURI(requestedString);
url.authenticate = true;
serverURL.addEventListener(IOErrorEvent.IO_ERROR, treatIO);
serverURL.addEventListener(Event.COMPLETE, loadData);
try{
serverURL.load(url);
}catch(e:ArgumentError){trace("ArgError: " + e.message);}
catch(e:SecurityError){trace("SecError: " + e.message);}
}
private function treatIO(e:IOErrorEvent):void{
trace(e.text);
}
private function loadData(e:Event):void{
trace("loaded");
connector.htmlObject.htmlText = serverURL.data as String;
trace(serverURL.data);
}
explanation: mainClass is an mxml file with just a button and an html object in it.
Note: I have done the recommended thing of adding to Flex the certificate.
Anyone out there that can assist with this?
Edit:
I also tried with the URLStream class and it still doesn't handle it, seems like I can't actually get a connection to the server...
Even tho I do connect to it in a browser or even SoapUI
We faced the same problem on some machines (Win7 64bit), unfortunatelly still not solved. Maybe this is relevant:
http://forums.adobe.com/message/4028647#4028647
When I ran into this problem it was caused by my hosting company introducing an inconsistency between the name in the SSL certificate and the URL I was calling, when I replaced https://www.example.com/ with https://example.com/ everything started to work again.