Solved

handling dispatched object from zend amf server

Posted on 2009-04-04
5
656 Views
Last Modified: 2013-11-11
hello experts!
i am trying to create simple login form in flex which should communicate with mysql via zend_amf_server. so far i created a custom component with a login form which sends request to RemoteObject, and on php side it checks if username/password are correct and returns that user's data... in my main application i am using states to show either login form or logged content. i would like to pass one of the user's data values (UID) to my main application and send its value to another RemoteObject which would get some other user's information from database and at the end show another state.

i am stuck with dispatching an event (at least i think so). in my loginForm component (see code) i have some conditions to check if username/password are entered.
when i run my application, and leave both fields in a form blank i get correct error Alert.show("No username??", "ERROR");
when i enter username and leave password blank i also get correct error - Alert.show("Password is blank??", "ERROR");
when i enter wrong username and/or password i get correct error - Alert.show("Wrong username and/or password.", "ERROR");

BUT, if i enter CORRECT username and password my application just 'stops'... status bar in browser says 'transferring data from localhost' and nothing happens.

in put a breakpoint at line 35:
dispatchEvent(e);
and run in debug mode. i enter correct user/pass and my script stops. in that moment i can see that i have 3 interesting things:

- event.result which is of type 'Array' and contains user's information. i need UID from here.
- i wrap my array in ArrayCollection (i should do that if i want to bind stuff from this point, right??) and therefore in my variables list i also have this.userArrCol which is of type 'ArrayCollection' and it is good.
- next, since i told my script to do so, i have e.UID (e is of type 'LoginEvent') which actually contains information i need (UID = some number!)

at this point i think that everything works fine.
so, what is happening with my main application? am i not listening for a login event there? why when i enter user/pass nothing happens?

thanks for help!
// loginForm.mxml component
//
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml" title="login">
	
	<mx:RemoteObject id="userRemote" source="user" destination="zend" fault="faultHandler(event)" showBusyCursor="true">
		<mx:method name="getUser" result="getUserListener(event)" fault="faultHandler(event)" />
	</mx:RemoteObject>
	
	<mx:Metadata>
		[Event(name="login", type="events.LoginEvent")]
	</mx:Metadata>
	
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.rpc.events.ResultEvent;
			import mx.controls.Alert;
			import events.LoginEvent;
			import mx.rpc.events.FaultEvent;
			
			[Bindable]
			public var UID:int;
			
			[Bindable]
			protected var userArrCol:ArrayCollection;
			
			private function getUserListener(event:ResultEvent):void{
				if (loginUser.length > 0){
					if (loginPass.length > 0){
						userArrCol = new ArrayCollection(event.result as Array);
						if (userArrCol.length > 0){
							var e:LoginEvent = new LoginEvent(UID);
							e.UID = userArrCol.getItemAt(0).UID;
							dispatchEvent(e);
						} else {
							Alert.show("Wrong username and/or password.", "ERROR");
						}
					} else {
						Alert.show("Password is blank??", "ERROR");
					}
				} else {
					Alert.show("No username??", "ERROR");
				}
			}
			
			private function faultHandler(fault:FaultEvent):void{
				Alert.show("General error.", "ERROR");
			}
		]]>
	</mx:Script>
		
	<mx:Label x="10" y="12" text="username"/>
	<mx:TextInput x="104" y="10" id="loginUser"/>
	<mx:Label x="10" y="42" text="password"/>
	<mx:TextInput x="104" y="40" id="loginPass" displayAsPassword="true"/>
	<mx:ControlBar>
		<mx:Button id="loginButton" label="LOGIN" click="{userRemote.getUser(loginUser.text, loginPass.text)}"/>
	</mx:ControlBar>
</mx:Panel>
//
// END loginForm.mxml
//
//
// myapp.mxml main application
//
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:comps="components.*"
	currentState="login">
	
	<mx:RemoteObject id="userDataRemote" source="userData" destination="zend" fault="faultHandler(event)" showBusyCursor="true">
		<mx:method name="getUserData" result="getUserDataListener(event)" fault="faultHandler(event)" />
	</mx:RemoteObject>
    
	<mx:states>
	<mx:State name="login">
		<mx:AddChild position="lastChild">
			<comps:loginForm id="login"
				horizontalAlign="center"
				login="doLogin(event)"/>
		</mx:AddChild>
		<mx:SetStyle name="verticalAlign" value="middle"/>
	</mx:State>
	<mx:State name="main">
		<mx:AddChild position="lastChild">
			<comps:main id="main"
				width="100%" height="100%"
				horizontalAlign="center"/>
		</mx:AddChild>
	</mx:State>
	</mx:states>
 
	<mx:Script>
		<![CDATA[
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			import mx.controls.Alert;
			import events.LoginEvent;
			import edu.school.userDataVO;
			
			private function doLogin(event:LoginEvent):void{
				var UID:int = event.UID;
				userDataRemote.getUserData(UID);
			}
			
			private function getUserDataListener(event:ResultEvent):void{
				//
				currentState = "main";
			} 
			
			private function faultHandler(fault:FaultEvent):void{
				Alert.show("error #100", "ERROR");
			}
			
		]]>
	</mx:Script>
		
</mx:Application>
//
//
// END myapp.mxml
//

Open in new window

0
Comment
Question by:joy_de_vivre
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
  • 2
5 Comments
 
LVL 19

Expert Comment

by:Gary Benade
ID: 24085462
Hi Joy

If you put a breakpoint on line 102, does the code stop there?
0
 
LVL 19

Expert Comment

by:Gary Benade
ID: 24085529
var e:LoginEvent = new LoginEvent('login');
e.UID = userArrCol.getItemAt(0).UID;
dispatchEvent(e);

If it works I'll explain a bit more :)
0
 

Author Comment

by:joy_de_vivre
ID: 24092991
hey hobbit =)
sorry for delay i was absent for a few days..
first to tell you, yes, your example is working to some point... i should pass 2 arguments to my LoginEvent, but you couldn't know that because i never attached that as code... so here it is now...

i must tell you also that while i was absent i did have some flex documentation and i was reading it and for now it seems to me that somehow i am missing the whole point about flex->zend_amf->php->mysql communication... well, maybe not completely, but it is very confusing to me... maybe because of too much information in short period of time =)

after that, i am also confused with flex itself... bubbling, async token, remoteobject, passing variables from result event to other components, etc... so i think i will have to spend lots of time reading and watching help...

i can't wait for your explanation about your piece of code, i just hope it will be mega-beginner explanation as i am nothing more than that =)

thanks!
package events
{
	import flash.events.Event;
 
	public class LoginEvent extends Event
	{
		
		public var UID:int;
		
		public function LoginEvent(type:String, UID:int){
			super(type);
			this.UID = UID;
		}
	}
}

Open in new window

0
 
LVL 19

Accepted Solution

by:
Gary Benade earned 500 total points
ID: 24094242
Hi Joy

Flex is a bit tricky, you struggle a bit and then one day something just clicks and you get it, you're almost there :)

Send me your email address if you want and I'll send you my ftp details, I have a couple of books that you may wish to read that got me going when I was learning flex.

OK, the explaination:

The code in your component below allows components declared in mxml to listen for an event without adding a listener in actionscript, it's all done for you behind the scenes.

        <mx:Metadata>
                [Event(name="login", type="events.LoginEvent")]
        </mx:Metadata>

The line above allows you to add the login="" below:
<comps:loginForm id="login"
  horizontalAlign="center"
  login="doLogin(event)"/>

you could do the same thing in actionscript with:
login.addEventListener("login", doLogin);

var e:LoginEvent = new LoginEvent('login', userArrCol.getItemAt(0).UID);
// e.UID = userArrCol.getItemAt(0).UID; //<-- you dont need this because it's set in the constructor call above now
dispatchEvent(e);

Whats very important above is the 'login' here:
new LoginEvent('login'

This gives the event its identity, and allows the code below to work:
[Event(name="login", type="events.LoginEvent")]  <-- the 'login' here must match the login in event above exactly to work

So, change your code to:

var e:LoginEvent = new LoginEvent('login', userArrCol.getItemAt(0).UID);
dispatchEvent(e);

or

dispatchEvent( new LoginEvent('login', userArrCol.getItemAt(0).UID));

hth
Gary
0
 

Author Comment

by:joy_de_vivre
ID: 24095332
hey gary!
yes, your code did the trick! i became aware of what i was doing wrong while reading some documentation, but your explanation is excellent for someone who is confused like me =)
in the other hand, this leads me to other problems, like, now when i got my e.UID how to manipulate with it and RemoteObject and AsyncToken and similar stuff... hmmm.. i think i miss some mega-basics here and i can't wait that moment when it will just click in my head =) lol
thanks for all the help, i will send you my email to pm or something...
i'm sure i'll be back with some other noob questions =)

marek
0

Featured Post

Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

There are times in your Flash CS4 application when you want more than a simple pointer or a hand, and it's hard to find an ideal walk-through to tell you what to do.  I spent a few days recently learning my way around making custom cursors in Flash,…
I have found that much of my time doing support ends up being a constant repetition of the same steps to different people.  Early on I stated using web pages with Frequently Asked Questions (FAQs) to alleviate most of the burden.  Sometimes this jus…
The goal of the tutorial is to teach the user how to use the auto adjust feature and what the different options do. When your video is not working right you can choose the auto adjust feature to help choose your settings.
The goal of the tutorial is to teach the user how to select which audio input to use. Once you have an audio input plugged into the laptop or computer, you will go into the audio input settings and choose which audio input you want to use.

751 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question