Joris Ooms
Joris Ooms

Reputation: 12048

Flex waiting for httpservice to return data

Seriously. I'm getting really annoyed by Flex. Is there a way to make it wait for an httpservice to get its data without having to use a timer?

At the moment my code looks like this:

protected function loginUser(event:MouseEvent):void
{
    if(txtEmail.text == "" || txtPassword.text == "")
    {
        Alert.show("Please complete all fields!", "Oops!");
    }
    else
    {
        user = new User(txtEmail.text, txtPassword.text);
        user.login(user);

        var loginTimer:Timer = new Timer(1000, 1);
        loginTimer.addEventListener(TimerEvent.TIMER_COMPLETE, dispatchLoginEvent);
        loginTimer.start()
    }
}

When I do user.login(), it sends a request with a HTTPservice from my external AS class. In the result event handler for this httpservice, I set a public variable to true or false, depending on whether the user's credentials are correctly in the DB.

I then use a getter to get that boolean value. However, without the timer, it always returns false because my code is faster than the event result handler. If that makes sense.

So I have to use a timer to stall my application for one second.. But seriously, that doesn't make sense to me. There has to be a better way, no?

I can provide more code if anyone's willing to help me out with this. Thanks.

Upvotes: 2

Views: 1534

Answers (3)

Neeraj
Neeraj

Reputation: 8532

Incase you are using HttpService object , I think the right way to go around is to use the "ResultEvent" and the "FaultEvent" on this HttpService object to process the data, after it has arrived.

You can see the following examples on how to use the HttpService object so that , it triggers a function after the data has been completely received from the server.

http://help.adobe.com/en_US/Flex/4.0/AccessingData/WS2db454920e96a9e51e63e3d11c0bf69084-7fdc.html

http://help.adobe.com/en_US/Flex/4.0/AccessingData/WS2db454920e96a9e51e63e3d11c0bf69084-7fdc.html#WS2db454920e96a9e51e63e3d11c0bf66651-7ff3

Upvotes: 0

Amy Blankenship
Amy Blankenship

Reputation: 6961

It seems you didn't completely understand my answer to your other question.

//Note the argument should NOT be a Mouse event, because that would be dispatched by a View.
//you should not have this kind of business logic in a View
protected function loginUser(event:UserEvent):void {
   //validate before even trying to create a user, since this
   //has the side effect of running an HTTPService call
   if (event.login != null && event.password != null) {
      user = new User(event.email, event.password);
      //these are plain old events dispatched by your user 
      //Note that strictly speaking a user should not be retrieving itself
      user.addEventListener('loginSuccess', onLoginSuccess);
      user.addEventListener('loginFailed', onLoginFailed);
   } else {
      dispatchEvent(new Event('incompleteUserDetails'));
   }

}

protected function onLoginSuccess(e:Event):void {
   //do your thing here
}

protected function onLoginFailed(e:Event):void {
   //trigger your error handling logic here
}

Your UserEvent Class should look something like this:

package service.event {
   public Class UserEvent extends Event {
      public static const REQUEST_LOGIN:String = 'requestLogin';
      //you may have other events that apply to users as well

      public var email:String;
      public var password:String;

     public function UserEvent (type:String, email:String, password:String):void {
         //I assume this will be dispatched from a View, given your existing code, so it will bubble by default
         super(tyoe, true, true);
         this.email=email;
         this.password=password;
     }
     override public function clone():Event {
        return new UserEvent(type, email, password);
     }
   }
}

You would dispatch that from the View based on the values of your email and password fields and listen for it higher up on the display list.

Upvotes: 1

Gareth Davis
Gareth Davis

Reputation: 28069

The correct pattern to use is a call back or an event listener on your User object.

protected function loginUser(event:MouseEvent):void
{
    ...

    user = new User(txtEmail.text, txtPassword.text);
    // pass a callback function to the login method 
    user.login(user, function(result:Boolean):void{
            // do something with the result
    });    
}

You'll have to excuse my ActionScript I haven't done any in a little while. But hopefully you get the idea. You should never get your self into a position of setting a timer to poll a boolean on an object in Flex, the answer is always to register a listener or some description.

Upvotes: 0

Related Questions