Volter
Volter

Reputation: 173

no error but not responding

I am noob in Flex/Actionscript so I have the code where compiler doesn't show error but code returns nothing. Can you help me to fix it?

Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
               xmlns:s="library://ns.adobe.com/flex/spark" 
               xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="main()">
    <fx:Script>
        <![CDATA[
            include 'AS/main.as';

            private function main():void {
                Label1.text = Login('irakli','password1');
            }

        ]]>
    </fx:Script>
    <s:Label id="Label1" x="370" y="176" text="Label"/>
</s:Application>

main.as

// ActionScript file
import flash.events.*;
import flash.net.*;

var Answer:String;

function Login(username:String, password:String){
    var loader:URLLoader = new URLLoader();
    var request:URLRequest = new URLRequest('http://localhost/hosting/index.php');

    request.method = URLRequestMethod.POST;
    var variables:URLVariables = new URLVariables();
    variables.username = username;
    variables.password = password;
    request.data = variables;

    //handlers
    loader.addEventListener(Event.COMPLETE, function(e:Event):void{
        var loader:URLLoader = URLLoader(e.target);
        Answer = loader.data;
    });
    loader.load(request);

    var i:int = 1;
    while (i < 10000000000){
        if (Answer.length > 0){
            return Answer; 
            break;
        }
        i++;
    }
}

I know about that it is good to use event handler functions, but I want that this code worked in main.mxml Label1.text = Login('irakli','password1');

Upvotes: 0

Views: 199

Answers (4)

JeffryHouser
JeffryHouser

Reputation: 39408

I see a bunch of problems:

  1. Your function does not specify a return type, or an access modifier
  2. URLLoader is asynchronous, but it appears you want your code to run synchronously.
  3. Your anonymous function on the URLLoader complete event will not execute in-line; so the last half of your method will execute before the complete handler.

Try modifying things to break them up into two functions, like this:

public function Login(username:String, password:String):void{
    var loader:URLLoader = new URLLoader();
    var request:URLRequest = new URLRequest('http://localhost/hosting/index.php');

    request.method = URLRequestMethod.POST;
    var variables:URLVariables = new URLVariables();
    variables.username = username;
    variables.password = password;
    request.data = variables;

    //handlers
    loader.addEventListener(Event.COMPLETE, onLoaderComplete); 
    loader.load(request);
}

public function onLoaderComplete(e:Event):void{
 var loader:URLLoader = URLLoader(e.target);
 Answer = loader.data;
 label1.text = Answer;
}

In your creation complete handler, try something like this:

Login('irakli','password1');

It calls the method. And the value of the label is set in the complete handler. Your method of waiting for the results is creating, but unnecessary.

Upvotes: 1

shanethehat
shanethehat

Reputation: 15580

Sorry, but wanting this to work in this fashion is simply wrong. You have no guarantee that that absurd loop will work because it could easily complete before your load operation does. Also, having a function inline in your event handler is considered bad practice.

The correct approach to this would be to make Login a class, and listener for an event coming out of it in order to populate the text box.

This is how you could write Login as a class:

package {
    import flash.events.*;
    import flash.net.*;

    public class Login extends EventDispatcher
    {
        public function Login(username:String, password:String):void
        {
            var loader:URLLoader = new URLLoader();
            var request:URLRequest = new URLRequest('http://localhost/hosting/index.php');
            request.method = URLRequestMethod.POST;
            var variables:URLVariables = new URLVariables();
            variables.username = username;
            variables.password = password;
            request.data = variables;

            loader.addEventListener(Event.COMPLETE, loadCompleteHandler);
            loader.load(request);
        }

        private function loadCompleteHander(evt:Event):void
        {
            // set the event on out of the class
            dispatchEvent(evt);
        }
    }
}

So then you would use this like this:

var login:Login = new Login('irakli','password1');
login.addEventListener(Event.COMPLETE,setTheText);

function setTheText(evt:Event):void
{
    Label1.text = evt.target.data;
}

Of course if you don't want listeners in your mxml (and I can't understand why that would be), then I think your best approach would be to pass the target textField into your Login function and let it set the text in the inline handler. Something like:

Login('irakli','password1',Label1);

main.as

// ActionScript file
import flash.events.*;
import flash.net.*;
import flash.text.TextField

var targetTF:TextField;

function Login(username:String, password:String,textField:TextField){
    targetTF = textField;
    var loader:URLLoader = new URLLoader();
    var request:URLRequest = new URLRequest('http://localhost/hosting/index.php');

    request.method = URLRequestMethod.POST;
    var variables:URLVariables = new URLVariables();
    variables.username = username;
    variables.password = password;
    request.data = variables;

    //handlers
    loader.addEventListener(Event.COMPLETE, function(e:Event):void{
        var loader:URLLoader = URLLoader(e.target);
        targetTF.text = loader.data;
    });
    loader.load(request);
}

Upvotes: 1

Constantiner
Constantiner

Reputation: 14221

Sorry, but this is one of the ugliest ActionScript code I've ever seen :( Can't imagine what language you're came from. PHP?

First of all, please read some fundamentals before writing code.

About code in particular:

  • What is the purpose of include statement in your code? Why not inline code in the Script block. Your way of code modularization is the best idea to make code obscured and hard to read and support.
  • Please read and follow ActionScript naming and coding conventions. It is necessary when you share your code with somebody (team member or SO).
  • Your Login method isn't return anything. Why do you expect Login('irakli','password1') will produce any text?
  • Please understand asynchronous nature of Flash and ActionScript. To understand it better, please don't inline event handlers but create separate methods for them.

Upvotes: 1

Philipp Kyeck
Philipp Kyeck

Reputation: 18860

uiiuiui. there are multiple things wrong here.

try not to use variables/functions with capital letters

private var _myVar:String = "string";

private function myFunction():void
{

}

declare you variables/functions as either private/public/protected

define return type of your function

private function login (username:String, password:String):String
{

}

you don't hace to use includes here - just put your login() method in the Main.mxml

don't use anonymous functions in event handlers - define a custom named function instead:

loader.addEventListener(Event.COMPLETE, onComplete);

private function onComplete(event:Event):void
{
   // do sth here ...
}

and don't use a while loop to wait for the result of your URLLoader - that's what the eventlistener is for.

best thing would be, if you create a Login class which handles the login-backend-communication and returns the result (ok or not ok) depending on the answer of the server.

package
{
  public class Login
  {
    public function Login()
    {

    }

    public function doLogin(username:String, password:String):void
    {
       // do loader stuff here ...
       loader.addEventListener(Event.COMPLETE, onLoginResponse);
    }

    private function onLoginResponse(evt:Event):void
    {
       // check answer from server
       if (server.response == "ok")
       {
         dispatchEvent(new Event('logged_in'));
       }
    }
  }
}

Upvotes: 1

Related Questions