I'm using Actionscript 2.0 in combination with PHP, now I can make a call to my PHP file and receive data but apparently I have to use that data immediately, I cannot use it to fill my class variables.
This is what I want :
class user {
var lastname:String;
function user(in_ID:Number){
var ontvang:LoadVars = new LoadVars();
var zend:LoadVars = new LoadVars();
zend.ID = in_ID;
zend.sendAndLoad("http://localhost/Services/getUser.php", ontvang, "POST");
ontvang.onLoad = function(success:Boolean) {
if (success) {
lastname = ontvang.lastname;
} else {
lastname = 'error';
}
};
}
}
I've found out that this is a big issue in AS2, I found this post to work around it if you're loading XML data but I can't seem to get it to work with LoadVars :
http://www.actionscript.org/forums/showthread.php3?t=144046
Any help would be appreciated ..
When your onLoad handler is called, it is being called as if it were a member function of the LoadVars instance, and not your user instance.
There are several ways around this, one is to use Delegate.create() to create a function which will work as intended, for example:
import mx.utils.Delegate;
class user {
var lastname:String;
var ontvang:LoadVars;
function user(in_ID:Number){
ontvang = new LoadVars();
var zend:LoadVars = new LoadVars();
zend.ID = in_ID;
ontvang.onLoad = Delegate.create(this, onLoad);
zend.sendAndLoad("http://localhost/Services/getUser.php", ontvang, "POST");
};
}
function onLoad(success:Boolean) : Void
{
if (success) {
lastname = ontvang.lastname;
} else {
lastname = 'error';
}
}
}
Don't forget that the load is asynchronous - when you create one of your user objects, the member variables won't be immediately available. What you may need to do is let your user object be capable of signaling its readiness much like LoadVars does, (e.g. with a callback function provided by the caller) so that your app is driven by by these asynchronous events.
Related
I recently started delving into custom classes in AS3 (to hone my best-practices coding habits), and wanted to create a database class that allows a user to first instantiate a class that contains all the information necessary for methods within the class to add, delete, modify (etc) rows in a MySQL table (via PHP). Of course, this involves using URLRequest, URLLoader and so forth. My question is whether anyone as figured a way how to return data from a method specifically containing that var data without relying upon the method essentially dispatching an event (then having to create a listener rather than having that built into the class). For example,
var myDB:dataBase = new dataBase("dbase","table","username","pword");
//this creates an instance of a database class with methods like:
trace(myDB.fetch(1)); //gets first row of table as a delimited string
OR
if (myDB.delete(1)) {}
//returns Boolean true if delete of row 1 was successful
I found the answer below that contained a way to create a class that returns an event:
Combining URLRequest, URLLoader and Complete Event Listener In Actionscript 3.0?
but I want the method to return a string containing data from the database or a boolean confirmation, not to dispatch an event listener. Here is an example of the class I made:
package com.customClasses {
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequestMethod;
import fl.events.DataChangeEvent;
import flash.events.Event
public class dataBase {
public var dbs:String = "";
public var usr:String = "";
public var pwd:String = "";
public var tab:String = "";
var returnData:String = "";
// Constructor
public function dataBase(dbs:String, usr:String, pwd:String, tab:String) {
this.dbs = dbs;
this.usr = usr;
this.pwd = pwd;
this.tab = tab;
}
public function fetch(idn:uint, par:String):String {
var returnData:String = "blank";
var vUrlReq:URLRequest = new URLRequest ("dBase.php");
var vUrlVars:URLVariables = new URLVariables();
function onLoadVarsComplete(event:Event): void {
//retrieve success variable from our PHP script:
if(event.target.data.msg == "success") {
var rawData:URLVariables = new URLVariables( event.target.data );
returnData = rawData.fromPHP;
} else {
returnData = "failed!";
}
}
vUrlReq.method = URLRequestMethod.POST;
vUrlVars.dir=dbs; // name of table affected
vUrlVars.alpha=usr; // username
vUrlVars.beta=pwd; // password
vUrlVars.dbase=tab; // name of table affected
vUrlVars.func="fetch"; // function for php script to use
vUrlVars.idnum=idn; //if >0 search for record with that id
vUrlReq.data = vUrlVars;
var vLoader:URLLoader = new URLLoader (vUrlReq);
vLoader.addEventListener("complete", onLoadVarsComplete);
vLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
vLoader.load(vUrlReq);
return (returnData);
}
returnData returns "blank"... so I realize my method is not working as intended. I also realize there my be some scope issues with the returnData string, and that I am using a nested function (probably a no-no). Otherwise, any thoughts?
To do what you want, you can use a callback function or a DataEvent listener, like this :
DB.as :
package {
import flash.net.*;
import flash.events.*;
public class DB extends EventDispatcher {
public static const DATA_LOADED = 'data_loaded';
public function DB() {
}
public function getDataUsingDataEvent(file_path:String):void {
var url_loader:URLLoader = new URLLoader();
url_loader.addEventListener(
Event.COMPLETE,
function(e:Event):void
{
var event:DataEvent = new DataEvent(DATA_LOADED, true, false, url_loader.data);
dispatchEvent(event);
}
)
url_loader.load(new URLRequest(file_path));
}
public function getDataUsingCallback(file_path:String, callback:Function):void {
var url_loader:URLLoader = new URLLoader();
url_loader.addEventListener(
Event.COMPLETE,
function(e:Event):void
{
callback(url_loader.data);
}
)
url_loader.load(new URLRequest(file_path));
}
}
}
And then :
var db:DB = new DB();
db.addEventListener(
DB.DATA_LOADED,
function(event:DataEvent):void {
trace(event.data);
}
)
db.getDataUsingDataEvent('file_path');
db.getDataUsingCallback(
'file_path',
function(data:String):void {
trace(data);
}
)
Hope that can help.
As you've stated it, this can't be done in AS3. You cannot wait for an asynchronous operation (such as URLLoader/load()) before returning the function and continuing script execution.
What you can do, if you'd prefer not to use addEventListener() so much, is pass through callbacks, or implement method chaining of promises. These patterns are not necessarily better than using events, and have their own problems, but let you write code that is arguably more readable as a sequence. These patterns are common in Javascript (which has the same asynchronous behavior as ActionScript), for example jQuery. Beware of "callback hell" and "train wrecks". These techniques aim to make things simpler to write but sometimes make things more error prone.
I have been following a flash tutorial online and I have created a simple flash interface. I am trying to retrieve data from my SQL database via a PHP file and display. I get the following error when I compile:
Error #1009: Cannot access a property or method of a null object reference
var variables1:URLVariables = new URLVariables();
var varSend1:URLRequest = new URLRequest("databaseCall.php");
varSend1.method = URLRequestMethod.POST;
varSend1.data = variables1;
var varLoader1:URLLoader=new URLLoader();
varLoader1.dataFormat = URLLoaderDataFormat.VARIABLES;
varLoader1.addEventListener(Event.COMPLETE,completeHandler1);
variables1.comType = "requestEntries";
varLoader1.load(varSend1);
function completeHandler1(event:Event):void{
if(event.target.data.returnBody ==""){
gbOutput_txt.text = "No data coming through";
} else{
gbOutput_txt.condenseWhite = true;
gbOutput_txt.htmlText = "" +event.target.data.returnBody;
}
}
My code exactly matches the code that is used within the tutorial. I have modified the php file to simply return "" so the issue almost definitely lies within the action script...I think :S The compiler falls over when he completeHandler1 function is called. What do you think could be causing this?
Thanks in advance.
You need to declare the completeHandler1 function before you attempt to use it anywhere else.
Here is your code modified to describe what I am talking about.
var variables1:URLVariables = new URLVariables();
var varSend1:URLRequest = new URLRequest("databaseCall.php");
varSend1.method = URLRequestMethod.POST;
varSend1.data = variables1;
function completeHandler1(event:Event):void{
if(event.target.data.returnBody ==""){
gbOutput_txt.text = "No data coming through";
} else{
gbOutput_txt.condenseWhite = true;
gbOutput_txt.htmlText = "" +event.target.data.returnBody;
}
}
var varLoader1:URLLoader=new URLLoader();
varLoader1.dataFormat = URLLoaderDataFormat.VARIABLES;
varLoader1.addEventListener(Event.COMPLETE,completeHandler1);
variables1.comType = "requestEntries";
varLoader1.load(varSend1);
Give this a try and let me know if it works.
I have a UrlRequest in my Main Class, that does a request to a server in cakePHP, and its working fine, but when I do the exact same request in a click of a button its not working.
Can someone help me?
This is my code to do the request:
var token:String = LoaderInfo(root.loaderInfo).parameters.requestToken;
var myData:URLRequest = new URLRequest("users/personalInfo/"+token);
myData.method = URLRequestMethod.GET;
loader = new URLLoader(myData);
loader.addEventListener(Event.COMPLETE, onLoaded);
loader.dataFormat=URLLoaderDataFormat.TEXT;
loader.load(myData);
function onLoaded(e:Event):void {
MovieClip(this.root).gotoAndStop("main");
}
Click Handler
public function SaveProfileButton() {
addEventListener(MouseEvent.CLICK, mouseClick);
}
private function mouseClick(e:MouseEvent):void{
MovieClip(this.root).output.text = "loading...";
send();
}
send() is the code to do the request.
Thanks
I think you may need a cross domain policy xml on your server where the php is. 99% sure. http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html
When I try to pass the url value to the controller action, action is not getting the required value.
I'm sending the value like this:
function value(url,id)
{
alert(url);
document.getElementById('rating').innerHTML=id;
var params = 'artist='+id;
alert(params);
// var newurl='http://localhost/songs_full/public/eslresult/ratesong/userid/1/id/27';
var myAjax = new Ajax.Request(newurl,{method: 'post',parameters:params,onComplete: loadResponse});
//var myAjax = new Ajax.Request(url,{method:'POST',parameters:params,onComplete: load});
//alert(myAjax);
}
function load(http)
{
alert('success');
}
and in the controller I have:
public function ratesongAction()
{
$user=$_POST['rating'];
echo $user;
$post= $this->getRequest()->getPost();
//echo $post;
$ratesongid= $this->_getParam('id');
}
But still not getting the result.
I am using zend framework.
Need alot more information here... How are you calling these functions? Are the values being passed at any stage in the chain? You mention "action", what are you actually referring to?
Further on that - if you mean that the values are not being handled within the PHP section, are you using the correctly named parameters? I see your Javascript code mentioned one parameter called "artist", but the PHP code mentions "rating" alone.
There is basic persistence of Javascript vars/etc. You call a function/method, and the next time you call that same function/method, it is holding the data from the last time.
You can delete the vars when you are done with them, but that removes the advantage of using the code again for that instance.
So what is the proper way to write code which can be reused, on different elements, inside the same page.
Therefore, I need the ability to write code so that I can point it at several different elements, and then interact with that code segregated for each element.
So in PHP (as an example) I would do:
$element1 = new MyClass();
$element2 = new MyClass();
$element3 = new MyClass();
in that case it's the same code running in three segregated scopes. How can I do this properly with JS. Even using jQuery's extend() gives me problems.
Thanks.
Use the var keyword when defining local variables (otherwise they'll default to globals).
function foo() {
var i;
// code code code code
}
To create an instance in JavaScript you need to write a constructor function, and call that using new. For instance:
function MyClass( somevalue ) {
this.somevalue = somevalue;
this.somefunction = function() {
alert(somevalue);
}
}
var instance1 = new MyClass(1);
var instance2 = new MyClass(2);
var instance3 = new MyClass(3);
You can namespace your JavaScript to make it a lot like what you're after. See below for an example. It does sound like your problem is related to using global variables where you want to use local variables though - i.e. you declare var myvariable; outside of your function, but only want to use it and forget it within your function. In that case, declare the variable inside your function to make it local.
var MyNameSpace = function() {
return {
sayhello : function() {
alert("hello");
},
saygoodbye : function() {
alert("see ya");
}
};
}();
It sounds like what you're looking for is the ability to have instances of a class and have private data that's associated with each instance.
You can do this using the following technique:
function Foo()
{
// Member variable only visible inside Foo()
var myPrivateVar;
// Function only visible inside Foo()
var myPrivateFunction = function()
{
alert("I'm private!");
}
// Member variable visible to all
this.myPublicVar = "Hi, I'm public!";
// Function visible to all
this.myPublicFunction = function()
{
myPrivateVar = "I can set this here!";
}
}
You can create and use one of these using the following syntax:
var myFoo = new Foo();
myFoo.myPublicVar = "I can set this!";
myFoo.myPublicFunction();