Returning a string in Action Script 3.0 - actionscript-3

I'm really not familiar with Action Script 3 at all but I am with other languages.
I'm hoping someone could help me.
I'm attempting to make a modification to JWplayer so that an rtmp stream is retrieved via a PHP script rather than it being supplied in the HTML.
The code I currently have is below:
function useData(event:Event):void {
var data:String = event.target.data.toString();
}
/** Load content. **/
override public function load(itm:PlaylistItem):void {
_item = itm;
_position = 0;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, useData);
loader.load(new URLRequest("http://192.168.0.12/phpauth/play1.php"));
// Set Video or StageVideo
if(!_video) {
_video = new Video(320, 240);
_video.smoothing = true;
_video.addEventListener('renderState', renderHandler);
// Use stageVideo when available
if (_stageEnabled && RootReference.stage['stageVideos'].length > 0) {
_stage = RootReference.stage['stageVideos'][0];
_stage.viewPort = new Rectangle(0,0,320,240);
_stage.addEventListener('renderState', renderHandler);
}
attachNetStream(_stream);
}
// Load either file, streamer or manifest
if (_item.file.substr(0,4) == 'rtmp') {
// Split application and stream
var definst:Number = _item.file.indexOf('_definst_');
In the load function the file name to play is held in _item.file. I'm trying to make a call to a php script which then overwrites the value in _item.file. I've confirmed that the php is being called but I don't know how to get the data from the data string in the useData function into the _item.file string.
Any help would be really appreciated - I suspect this is a simple one but my lack of AS3 knowledge is making it really difficult.
Thanks,

Your problem basically about how to access a local variable in an event handler. A quick and dirty way can be to have an anonymous function used as a handler like:
loader.addEventListener(Event.COMPLETE, function(event:Event):void {
var data:String = event.target.data.toString();
_item.file = data;
});
This approach would work, because this anonymous function has access to the local variables inside load function as is. But, you need to be cautious that the anonymous function uses the variable exactly as the calling function is using. So, let's say there is a loop in load function and _item changes in every iteration of the loop. For that scenario, when load handler gets called, its _item would also have changed to the object which was last assigned to _item.
A far cleaner and OO approach can be to have a handler class like:
package {
public class LoadHandler {
private var _item:PlaylistItem;
public function LoadHandler(item:PlaylistItem) {
_item = item;
}
public function loadHandler(event:Event):void {
var data:String = event.target.data.toString();
_item.file = data;
}
}
and then have loader.addEventListener(Event.COMPLETE, (new LoadHandler(_item)).loadHandler). Hope that helps. BTW, LoadHandler could be made more generic to take and array of objects to be used and a callback function. loadHandler function, then could just call callback function with that array of objects.

If you are returning a simple string from PHP you should be able to use
event.target.data;
e.g. from PHP... echo "hello";
var data:String = event.target.data
You could try tracing the response to ensure you are getting something back from PHP.
You can either test this from within the IDE or install the Debug version of the Flash Player browser plugin.
trace("Response from PHP: "+event.target.data);
_item.file = event.target.data;
trace("_item.file: "+_item.file);

Related

as3 return value on loader complete

I am trying to get my function to return a value from a php script once it has loaded. I am having issues with the 'return' aspect. Trying to the the value of 'TheLink" from a function with a 'return' in it. It's usually null. What am I doing wrong here?
var theLink = loadAudio();
public function loadAudio():String
{
var req:URLRequest = new URLRequest("myScript.php");
var loader:URLLoader = new URLLoader(req);
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, Finished);
function Finished(e:Event)
{
var theValue = JSON.parse(e.target.data.audioLink);
return theValue;
}
}
A lot of things are wrong in your code but more important is that you cannot escape the asynchronous nature of AS3.
First thing first, even if AS3 wasn't asynchronous your code would still not work. The "loadAudio" never returns anything so theLink can never get any data. The 'Finished' method is the one return something but there's no variable to catch that data either.
Now the real stuff, AS3 is asynchronous that means that things will happen at a later time and this is why you need to pass an event listener in order to 'catch' when things happen. In your case the Event.COMPLETE will trigger at a later time (asynchronous) so there's no way for a variable to catch the result before the result is actually available so:
var theLink:Object = loadAudio();//this is not possible
The correct way is:
private var loader:URLLoader;//avoid GC
private var theLink:Object;//this will store result when available
//I assume you are using a class
public function MyClass()
{
loadAudio();//let's start loading stuff
}
private function loadAudio():void
{
var req:URLRequest = new URLRequest("myScript.php");
loader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.VARIABLES;
loader.addEventListener(Event.COMPLETE, handleLoaded);
loader.load(req);
}
private function handleLoaded(e:Event):void
{
theLink = JSON.parse(e.target.data.audioLink);
//done loading so store results.
}

JSON.parse(...).reelarray is null - ActionScript

in return i am getting null value
public function spin()
{
var decoded : Object;
trace("i am innnnnnn");
var sendLoaders:URLLoader;
var sendRequests:URLRequest;
sendLoaders = new URLLoader();
sendRequests = new URLRequest("http://localhost/getspinvalue/4");
var difvar:Array = [];
sendLoaders.addEventListener(Event.COMPLETE, botCompleted);
sendLoaders.load(sendRequests);
function botCompleted(e:*)
{
decoded = JSON.parse(e.currentTarget.data);
}
trace(decoded);
return decoded.reelarray;
}
well, the sendLoaders.load() is an asynchronous event, your function returns null since the botCompleted() function hasnt fired when the function returns
You need to continue the execution inside you botComplete function (if you need to do different things after each spin() you can pass a function that gets executed)
public function spin() {
var decoded : Object;
trace("i am innnnnnn");
var sendLoaders:URLLoader;
var sendRequests:URLRequest;
sendLoaders = new URLLoader();
sendRequests = new URLRequest("http://localhost/getspinvalue/4");
var difvar:Array = [];
sendLoaders.addEventListener(Event.COMPLETE, botCompleted);
sendLoaders.load(sendRequests);
trace("request sent")
}
function botCompleted(e:*) {
decoded = JSON.parse(e.currentTarget.data);
trace("data recieved:" + decoded)
//CONTINUE EXECUTION HERE
}
URLLoader.load is an asynchronous method, it means that it spawns a process to load URL, and the execution of spin continues. So it returns a value at once. The botCompleted function is executed when the request is fulfilled, later. Something like that:
sendLoaders.load()
return value
botCompleted()
So you should rely on the botCompleted function, rather than on the return value. All the logic that depends on the decoded result should be triggered inside the botCompleted function.
function botCompleted(e:Event):void {
decoded = JSON.parse(e.currentTarget.data);
handleDecodedResult(decoded);
}
i want my spin method to return the decoded value .so how can i change
my code.
This is not possible. The JSON data is loaded asynchronously, but the function returns synchronously. In other words, the spin() function returns immediately (like all functions do), but the URLLoader doesn't complete until later in time. It doesn't matter that the botCompleted handler is written before your return statement, it won't get called until later. This is what event handlers are for: to handle asynchronous events.
What you can do is pass in callback functions. For example:
function spin(callback:Function):void {
var loader:URLLoader = new URLLoader();
// .. load
loader.addEventListener(Event.COMPLETE, complete);
function complete(e:Event):void {
var decoded:Object = JSON.parse(e.target.data);
callback(decoded);
}
}
Now you can call your spin function and pass an anonymous function in the context that you call spin, which almost makes it look synchronous:
spin(function(data:Object):void {
trace(data);
// Do stuff with data here
});
// Note: data is not available yet from here, only from inside the callback above
This is a common practice (in both AS3 and JS), though not without its pitfalls.

connection between Flex and FLash

I am working on a project, which is based on two main parts, the first part is done by Flex, and second one is a flash professional project, contains PROJECTNAME.fla and PROJECTNAME.as files. My question is how we can set some parameters in .fla project (e.g. usernames, user's images) from flex part. I explain main procedure by following;
Connect to server by flex part and get user's status
run .swf created by a flash professional project as described above
set some parameters in .swf file.
I have googled a lot, and I did not find any solution. (there was some solution that converts symbol to flex component, since it works for converting a single symbol). Any Idea will be appreciated.
There are several possibilities to pass the params from one swf (flex in your case) to another runtime loaded fla.swf:
1.Pass through the loading query params:
code in flex.swf:
public function astest()
{
var loader:Loader = new Loader();
addChild(loader);
loader.load( new URLRequest("astest1.swf?param1=value1&param2=value2"));
}
access params from fla.swf:
public function astest1()
{
if(stage)
onAdded();
else
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
protected function onAdded(event:Event = null):void
{
//root.loaderInfo.parameters - params of this swf file
//stage.loaderInfo.parameters - params of core swf file
var params:Object = root.loaderInfo.parameters;
for (var param:String in params)
trace(param,"=",params[param]);
}
output:
param2 = value2
param1 = value1
lacks of this method:
-one time usage, you can pass params only one time when loading
-the second swf must be runtime loaded by url, you can't embed it (or one of the class withing it) for example.
2.Runtime communication through the events
I recommend to use this method, it hasn't lacks of previous one.
Example of using stage as the global common dispatcher.
flex.swf:
public function astest()
{
addEventListener("ready", onReady);
var loader:Loader = new Loader();
addChild(loader);
loader.load( new URLRequest("astest1.swf"));
}
protected function onReady(event:Event):void
{
sendParams("param1=value1&param2=value2");
}
protected function sendParams(params:String):void
{
stage.dispatchEvent(new DataEvent("params", false, false, params));
}
fla.swf:
public function astest1()
{
if(stage)
onAdded();
else
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
protected function onAdded(event:Event = null):void
{
stage.addEventListener("params", onParams);
//fire event with bubbling that anables handling it in the parent swf
dispatchEvent(new Event("ready", true));
}
protected function onParams(event:DataEvent):void
{
var data:String = event.data;
trace(data);
}
output:
param1=value1&param2=value2
with this approach you send as many params as you need, you alsa can create custom event to pass Object parameters but in this case both project must have this cusom event in there source paths.

AS3 Serialization

What I'm trying to do:
-Have objects in a toolbar, drag and dropable onto a movieclip (they then become a child of the movieclip). Once this is done, I want to be able serialize this object, so I can save it to a file. Then, I can reload this file, and continue draging/dropping things onto/off of this movieclip.
How I'm doing it:
public class Serialization {
public static function serializeToString(value:Object):String{
if(value==null){
trace("null isn't a legal serialization candidate");
}
var bytes:ByteArray = new ByteArray();
bytes.writeObject(value);
bytes.position = 0;
var be:Base64Encoder = new Base64Encoder();
be.encode(bytes.readUTFBytes(bytes.length));
return be.drain();
}
public static function readObjectFromStringBytes(value:String):Object{
var dec:Base64Decoder=new Base64Decoder();
dec.decode(value);
var result:ByteArray=dec.drain();
result.position=0;
return result.readObject();
}
}
This is where call the function/write it to the file:
var fr:FileReference = new FileReference;
fr.addEventListener(Event.COMPLETE, success);
var txtString:String = new String();
txtString = save.Serialization.serializeToString(pagePic);
trace(txtString);
fr.save(txtString, "test.txt");
Unfortunately, txtString appears to be blank. Am I approaching this wrong?
Side notes:
This is being developed for a mobile platform.
Unfortunately MovieClips, Sounds, and other resources cannot be serialized. My solution is to create a custom class that will store all my properties and reassign them upon loading, or just write to/parse a text file when saving/loading.

AS3 Using variable from one function in another - not working

Can't seem to get the value of myXML outside the function, despite being declared outside. What am I missing here? The data loads and traces correctly inside the function.
var myLoader:URLLoader = new URLLoader();
myLoader.load(new URLRequest("flightPlannerBoard.xml"));
var myXML:XML;
// Check XML data fully loaded
myLoader.addEventListener(Event.COMPLETE, processXML);
function processXML(e:Event):void {
myXML = new XML(e.target.data);
//trace(myXML);
}
trace(myXML);
Because ActionScript is asyncronous as others have said, you cannot control the flow of execution by code placement. What you must do is control execution through the events, and so whatever actions you want to perform with the loaded XML should be in the processXML function or in another function that is called from processXML:
var myXML:XML;
function processXML(e:Event):void {
myXML = new XML(e.target.data);
trace(myXML); //this trace will work
doNextAction();
}
function doNextAction():void {
trace(myXML); //this trace will also work
}
You should declare your XML variable outside your function in order to be able to use it in another function
private var myXML:XML;
Actionscript is an asynchronous language, meaning the trace "outside" the callback will be called before the file has loaded. The execution order in your case is:
create instance of URLLoader
start loading file
add event listener to listen to the complete event
trace out myXML
(or at some point later) finish loading xml file