Reading MySQL result using PHP in AIR - actionscript-3

I was wondering if some one could explain how I can read a MySQL result array in AS3.
I am using:
var loader:URLLoader = new URLLoader();
var urlReq:URLRequest = new URLRequest("http://domain.com/get-api.php");
var urlVars:URLVariables = new URLVariables();
loader.dataFormat = flash.net.URLLoaderDataFormat.TEXT;
urlReq.method = URLRequestMethod.POST;
urlReq.data = urlVars;
urlVars.mySubmittedRateID = GlobalVariables.mySubmittedRateID;
urlVars.myPostcode = GlobalVariables.currentPostcode;
loader.addEventListener(flash.events.Event.COMPLETE, getDataOnComplete);
loader.load(urlReq);
to pass a parameter (2 in fact) to the get-api.php file. In the file I PHP reading in the parameters and a normal SQL select where statement which gets all the results matching the parameters.
My getDataOnComplete function is:
private function getDataOnComplete(event:flash.events.Event):void
{
var loader:URLLoader = new URLLoader(event.target);
var resultsArray:Array = JSON.decode(loader.data);
}
My PHP:
$row_array['done'] = "true";
return json_encode($row_array);
Error:
Error: Error #2101: The String passed to URLVariables.decode() must be a URL-encoded query string containing name/value pairs.
at Error$/throwError()
at flash.net::URLVariables/decode()
at flash.net::URLVariables()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()
For some reason I cant even get to the getDataOnComplete function.

Your php mysql result will be array then
In php side you need to convert into result array into json_encode($result_array) like
echo json_encode($result_array); //Note here not return statement;
In as3 side
you can use latest AIR SDK having native JSON class (Here using AIR class) or as3corelib to parse JSON data.
private function getDataOnComplete(event:flash.events.Event):void
{
var resultObj:Object = event.target.data;
var resultsArray:Object = JSON.stringify(resultObj);
}
For more details pass-an-array-from-php-to-actionscript-3

Related

How to parse JSON in AS3

I'm trying to build an application in Flash, but I have a problem. I'd like to parse the JSON from an web URL.
link: JSON text to parse
I'd like to get the JSON string "title" from here. Is there a way I can do it?
It says undefined.
var VidDataLoader = new URLLoader();
var VidUrl = "THEURL" + param1.getString(0);
trace(VidUrl)
VidDataLoader.load( new URLRequest(VidUrl))
VidDataLoader.addEventListener(Event.COMPLETE, doneit)
function doneit(e:Event){ var myData:Object = JSON.parse(VidDataLoader.data);
You are trying to reach the data from the VidDataLoader class, but the loaded data is part of the event object:
public function JSONLoader() {
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, decodeJSON);
loader.load(new URLRequest("myfile.json"));
}
// use the event to get the data
private function decodeJSON(e:Event):void {
var loader:URLLoader = URLLoader(e.target) ;
var jsonObject:Object = JSON.parse(loader.data);
}

Running-order of nested function-calls delayed/altered due to URLloader in AS3?

First of all: English is not my first language. ;-)
I am compiling the following code:
var sqldata:String;
function sql(saveorload,sqlstring) {
var sqlloader = new URLLoader();
var sqlrequest = new URLRequest("http://***/sql.php");
sqlrequest.method = URLRequestMethod.POST;
sqlloader.addEventListener(Event.COMPLETE, sqldonetrace);
var variables:URLVariables = new URLVariables();
variables.sqlm = saveorload;
variables.sqlq = sqlstring;
sqlrequest.data = variables;
sqlloader.load(sqlrequest);
}
function sqldonetrace(e:Event) {
sqldata = e.target.data;
}
sql("1","SELECT * FROM songs WHERE `flag2` LIKE '0'");
trace (sqldata);
So, here comes the problem:
"sqldata" is traced as "null". AS3 seems to run "sql", then "trace" and then "sqldone", but i would need sql -> sqldone -> trace...
I can't put the trace-command in the sqldone-function because it is stored as *.as and loaded at different points in my .swf and not always followed by only a trace-command.
Any Ideas/hints/flaws in script?
Actionscript is, by design, an event driven language. It also guarantees that the code executes in a single thread i.e. if a function call starts, no other(new call) actionscript code would execute until the first call finishes.
That being said, what you should have is to pass a complete handler to sql(...).
function sql(saveorload:String, sqlstring:String, completeHandler:Function):void
{
var sqlloader = new URLLoader();
var sqlrequest = new URLRequest("http://***/sql.php");
sqlrequest.method = URLRequestMethod.POST;
sqlloader.addEventListener(Event.COMPLETE, completeHandler);//tell urlloader to use the complete handler passed in parameters
var variables:URLVariables = new URLVariables();
variables.sqlm = saveorload;
variables.sqlq = sqlstring;
sqlrequest.data = variables;
sqlloader.load(sqlrequest);
}
And then use it from some other place like:
sql("1","SELECT * FROM songs WHERE `flag2` LIKE '0'", sqldonetrace);
function sqldonetrace(e:Event)
{
var sqldata:String = e.target.data;
trace (sqldata);
}
Also, I think you should check for error events from urlloader. Pass another parameter to sql as errorHandler

Actionscript 3 Flex 4.5 Serialization/Deserialization issue?

I'm having a particular issue deserializing an object in a Flex 4.5 Mobile project. I've connected to a Webservice fine and populate a ListBox fine. I can select the item and get the details just fine as well but after serializing the object and trying to deserialize it; the Object definition is getting lost somewhere.
I have a variable for when the user selected the request in a List
private var selectedReq:ServiceRequest;
//Here we instantiate the local variable when user select id in ListBox
selectedReq = event.currentTarget.selectedItem as ServiceRequest;
Each Service Request the user chooses to save will call this method.
private function writeServiceRequest():void {
var filename:String = buildFileName();
var file:File = File.applicationStorageDirectory.resolvePath(filename);
if (file.exists)
file.deleteFile();
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
//selectedReq is the private var of the users selected item
fileStream.writeObject(selectedReq);
fileStream.close();
}
When the users want to view the request this method is called.
private function readServiceRequest():ServiceRequest {
var filename:String = buildFileName();
var file:File = File.applicationStorageDirectory.resolvePath(filename);
if (!file.exists) {
return null;
}
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.READ);
var objReq:ServiceRequest = fileStream.readObject() as ServiceRequest;
fileStream.close();
return objReq;
}
The Class Object is similar to.
public var id:uint;
public var requisitioner:String;
public var requestItems:ArrayCollection //Webservice it's actually List<requestItems>
public var requestProcesses:ArrayCollection // WSDL it's actually List<>
When I try to read/deserialize like
//This line is null but the file exist and the object was written
var objReq:ServiceRequest = readServiceRequest() as ServiceRequest;
if(objReq) {
selectedReq = objReq;
}
If I do not cast the readServiceRequest() as ServiceRequest and simply return an Object; I can iterate through the Object and get the correct values returned from the serialized object.
I can only assume the Classes that Flex created from the Webservice may be causing this? If the values are getting written but not the object type then something has to be lost in the serialization - correct?
Sorry for all the details but I'm a little lost at this time.....any help would be appreciated.
RL
var objReq:ServiceRequest = readServiceRequest() as ServiceRequest;
The above line will continue to return null.
I bet that if you modify it in the following way:
var objReq:ServiceRequest = ServiceRequest(readServiceRequest());
You'll get a run-time exception with a message similar to Can't cast ObjectProxy to ServiceRequest
If that's the case, then the reason you get this is because the AMF serializer doesn't preserve the type information when serializing the ServiceRequest-instance.
In order to fix this you need to call flash.net.registerClassAlias() before the serialization/deserialization.
flash.net.registerClassAlias("fully.qualified.name.ServiceRequest", ServiceRequest);
Try if this work.
Check if event.result is ByteArray.
Read/store the event.result as ByteArray.
var byteArray:ByteArray = event.result as ByteArray;
Get/Deserialize Object using readObject() function.
var object:Object = byteArray.readObject();
Cast to targetted object type. ServiceRequest in your case.
var tartgettedObject:ServiceRequest = object as ServiceRequest;
or
var tartgettedObject:ServiceRequest = ServiceRequest(object);
My bad for not signing in before posting the question.
I did use registerClassAlias which did not help. I did find on the Adobe forum other simular issues and the constant feedback was the problem is most likely caused by the Object Class loosing it's attributes during the file write reason being the Class Objects are written when the Datasource is created from the Webservice. Since my original question we decided to use SQLite which is working perfectly fine - thanks for all you help.
RL

AS3 ByteArray " The supplied index is out of bounds" Error

I'm working on an application and I need to save an AS3 object to a db.
Here's what I'm doing:
private function getComplete(e:Event)
{
var getVars:URLVariables = new URLVariables(unescape(e.target.data));
var _saveData_obj = readObjectFromStringBytes( getVars.saveData);
// do something with the save data....
}
public function SaveGame() {
var _save_data:Object = _puzzle.dataForSaving;
var _serialized_string = escape(serializeToString(_save_data));
var _round_time = Math.round( _elapsed_time);
var _token = MD5.hash( _id +
_difficulty +
"mysomewhatsecretstringhere" +
_round_time );
var request:URLRequest =
new URLRequest( _home + 'savegame.php' );
request.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.saveData = _serialized_string;
variables.time = _round_time;
variables.id = _id;
variables.dif = _difficulty;
variables.token = _token;
request.data = variables;
var loader:URLLoader = new URLLoader (request);
loader.addEventListener(Event.COMPLETE, postComplete);
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.load(request);
}
public function LoadGame() {
var request:URLRequest =
new URLRequest( _home + 'loadgame.php?id='+_id+"&dif="+_difficulty);
request.method = URLRequestMethod.GET;
var loader:URLLoader = new URLLoader (request);
loader.addEventListener(Event.COMPLETE, getComplete);
loader.addEventListener(IOErrorEvent.IO_ERROR, netError);
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.load(request);
}
public static function serializeToString(value:Object):String{
if(value==null){
throw new Error("null isn't a legal serialization candidate");
}
var bytes:ByteArray = new ByteArray();
bytes.writeObject(value);
bytes.position = 0;
trace ("Saved: "+bytes.length);
var be:String = Base64.encodeByteArray(bytes);
return be;
}
public static function readObjectFromStringBytes(value:String):Object {
var result:ByteArray=Base64.decodeToByteArray( value) as ByteArray;
result.position = 0;
var the_obj:Object = result.readObject();
return the_obj
}
The problem is that I keep getting a "The supplied index is out of bounds" error when I try to read the object from the Base64 string.... I checked if the saved string and the loaded string are the same. Tried to save the Base64 string to a shared object and retrieve it - that works fine ... the only problem is when I save and load to/from the server.
Can you guys help me? What am I doing wrong?
Thanks.
try using ba.writeMultiByte(string, 'utf-8') and ba.readMultiByte(ba.bytesAvailable, 'utf-8') without converting to object
Ok, so it looks like we've come to a series of steps you can take to debug what's going on.
(In save game) make sure that unescape( variables ).saveData == _puzzle.dataForSaving. If this does not work, then your issue is with either escape or unescape. I have to admit
I am suspicious here, you should never need to escape data for a POST once it has been Base64 encoded (as3crypto's Base 64 encoding will return only one of these characters: ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=. Those are all legit in a POST) and your URLLoader should take care of making it a legit request, so I have difficulty seeing the need.
It is more consistent (and more expected) to have escape and unescape both accept strings as parameters and return strings.
Instead of storing to the database and then retrieving, store to $_SESSION (or, if possible, just echo the value back). This will eliminate PHP as a possible culprit.
In PHP, make sure that $_POST['saveData'] == /* whatever you echo */. If it isn't, then you have a DB encoding issue. You need to make sure that whatever encoding is used in MySQL is the same as the one used in AS.
As an aside, when working with AS, you'll often find it easier to use $_REQUEST instead of $_POST or $_GET. Since the requests are more or less abstracted, the URLRequests of AS don't really need to worry about being RESTful, and it is a heck of a lot easier to work with than exclusively using POSTs.

how to read the data from the JSP in a MXML through actionscript?

We are collecting the data at run time in Collection object in JSP page. We want to read this data from the JSP in a MXML through actionscript.
pls share the sample if you have.
thanks,
Sudarshan
function loadData():void
{
var ldr:URLLoader = new URLLoader();
var request:URLRequest = new URLRequest("page.jsp");
ldr.addEventListener(Event.COMPLETE, onLoad);
ldr.load(request);
}
private function onLoad(e:Event):void
{
var ldr:URLLoader = URLLoader(e.target);
trace(ldr.data);//traces the loaded string
//if the data is xml
/*
var myxml:XML = new XML(ldr.data);
trace(myxml.toXMLString());
*/
//update: answer to the comment:
//If the input string just lacks a root tag from being valid xml,
//you can introduce a dummy root tag.
var myxml:XML = new XML("<root>" + ldr.data + "</root>");
trace(myxml.data.toString()); //Hello
trace(myxml.value.toString()); //Hi
}
page.jsp should serialize the collection to appropriate format (xml/json/whatever) and return it.