Ultrashock Forums > Flash > ActionScript
Custom Event with multiple EventTypes and data
Member Blogs
 
Post Reply | View first unread | Rate Thread Search this Thread | Thread Tools | Display Modes

#1
Bookmark and Share!
Custom Event with multiple EventTypes and data
Old 2007-10-29

I'm really banging my head on this one.
For some reason I can't see how to do what I want. I have a custom Event Class

Code:
package {
	
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.EventPhase;
	
	public class RemotingEvent extends Event {
		// constants for the different event types
		public static const LOGIN_RESULT:String = "login_result";
		public static const IMAGE_UPLOAD:String = "image_upload";
		public static const USER_SIGNUP:String = "user_signup";
		
		public var dataObj:Object;
		public function RemotingEvent(type:String, data:Object, bubbles:Boolean=true, cancelable:Boolean=false) {
			
			// Pass constructor values to superClass constructor
			super(type, bubbles, cancelable);
			
			dataObj = data;
			
		}
		
		// override clone()
		public override function clone():Event {
			return new RemotingEvent(type, dataObj, bubbles, cancelable);
		}
		
		// override toString()
		public override function toString():String {
			return formatToString("RemotingEvent", "type", "dataObj", "bubbles", "cancelable", "eventPhase");
		}
		
	}
}
When I try to dispatch an event I get the error
Code:
1180: Call to a possibly undefined method dispatchEvent.
Here's the code for handling the dispatching of events. This is just one of the methods
from a large remoting class I have written. I have made sure all of my classes are imported.

Here's a list of classes:
import flash.net.NetConnection;
import flash.net.Responder;
import flash.events.*;
import RemotingEvent;

There are others but these are the relevant ones.

Code:
private static function handleLogin_Result(isValid:Array):void {
	// param @ isValid:Array -- Contains 2 items. [0]=="success or error", [1]=="The error string" 
			
	var responseObj:Object = {isAllowed:false, errMsg:""}; 			
	var errStr:String = isValid[0].toLowerCase();
			
	var evt:RemotingEvent;
			
	// check to see if the user has passed in a proper username and password
	if (errStr == "error") {
		// Error has occurred. 
		// Username / Password is incorrect.
		evt = new RemotingEvent(RemotingEvent.LOGIN_RESULT, {err:errStr});
				
				
	} else if (errStr == "success") {
		// Allow the user to login.
		evt = new RemotingEvent(RemotingEvent.LOGIN_RESULT, {err:errStr});
	}
	dispatchEvent(evt);
}
Can someone point out what exactly I'm doing wrong?
I just don't see it. Any help would be greatly appreciated.

Thanks.
postbit arrow 7 comments | 187 views postbit arrow Reply: with Quote   
neilm
Registered User
neilm is offline
seperator
Posts: 8
2001-11-04
seperator

Ultrashock Member Comments:
senocular senocular is offline Moderator senocular lives in United States 2007-10-29 #2 Old  
whatever class you're defining handleLogin_Result in needs to be an event dispatcher, either through extending EventDispatcher (or a subclass, like Sprite) or by implementing IEventDispatcher and using the EventDispatcher class to dispatch events for your instance in the implemented methods
Reply With Quote  
neilm neilm is offline 2007-10-29 #3 Old  
I had tried that but it still didn't seem to work.
Originally this was a static class. I changed it all over to not be static and now it all seems to work.
I can't see that being the only cause tho. Static classes should be able to dispatch events, shouldn't they?
Here's the constructor of the class as it was in the non-working state.

Code:
package {
	import flash.net.NetConnection;
	import flash.net.Responder;
	import flash.events.*;
	import flash.display.*;
	import RemotingEvent;


	public class Remoting extends Sprite {
		private static const SERVICE_URL:String = "http://www.theurl.com/path/to/gateway.php";
		
		private static var service:NetConnection;
		
		//  Constructor
		public function Remoting() {}

		// Sends the users login information to the server for validation.
		public static function login(u:String, p:String):void {
			// This method sends the login data to the server
			var responder = new Responder(handleLogin_Result, onFault);
			service.call("gateway.login", responder, u, p);
		}

		private static function handleLogin_Result(isValid:Array):void {
			// param @ isValid:Array -- Contains 2 items. [0]=="success or error", [1]=="The error string" 
			
			var responseObj:Object = {isAllowed:false, errMsg:""}; 			
			var errStr:String = isValid[0].toLowerCase();
			
			var evt:RemotingEvent;
			
			// check to see if the user has passed in a proper username and password
			if (errStr == "error") {
				// Error has occurred. 
				// Username / Password is incorrect.
				evt = new RemotingEvent(RemotingEvent.LOGIN_RESULT, {err:errStr});
				
				
			} else if (errStr == "success") {
				// Allow the user to login.
				evt = new RemotingEvent(RemotingEvent.LOGIN_RESULT, {err:errStr});
			}
			dispatchEvent(evt);
		}
	}
}
That's the code that wasn't/isn't working.
The way I ended up going just takes out all of the static types which forced me to create a Remoting Object
instead of just calling it directly.

Code:
// Old
Remoting.login(u, p);

// New
var remObj:Remoting = new Remoting();
remoObj.login(u, p);
I know it should work as a static class but I'm obviously missing something in there.

If you see what I've messed up I'd be interested to know what it was/is.
Or if I'm completely out to lunch in my thinking and there is a better way I'd like to hear that as well.
Thanks Senocular.
Reply With Quote  
senocular senocular is offline Moderator senocular lives in United States 2007-10-29 #4 Old  
static methods can't dispatch because the "instance" is the class itself, and that is an instance of Class which does not inherit from EventDispatcher.
Reply With Quote  
Nutrox's Avatar Nutrox Nutrox is offline Nutrox lives in United Kingdom 1 Blog Entries 13 Creative Assets 2007-10-29 #5 Old  
It should work with a singleton though.
Reply With Quote  
neilm neilm is offline 2007-10-31 #6 Old  
I think I'm going to end up going the singleton route as this particular class is going to be used in so many places within the app. I don't want to have multiple login's of the same user etc. so it's probably the best way to go for now. This was why I was trying to keep the static class. Thanks guys.
Reply With Quote  
Nutrox's Avatar Nutrox Nutrox is offline Nutrox lives in United Kingdom 1 Blog Entries 13 Creative Assets 2007-10-31 #7 Old  
Yeah, a singleton would be better IMO. They pretty much behave the same way as all-static classes do. I think the only time all-static classes are really needed is for utility classes and classes that simply contain parameter values (i.e. StageAlign and StageScaleMode etc).

It sounds like you are already familiar with singletons but I thought I would post the following code anyway. This is how I do things:

ActionScript Code:
  1. package
  2. {
  3.     /**
  4.      */
  5.     public class MySingleton extends EventDispatcher
  6.     {
  7.         //----------------------------------------------------------------------
  8.         //
  9.         // Private Properties
  10.         //
  11.         //----------------------------------------------------------------------
  12.        
  13.         /**
  14.          */
  15.         private static var singletonInstance:MySingleton = null;
  16.        
  17.         /**
  18.          */
  19.         private static var constructorLocked:Boolean = false;
  20.        
  21.         //----------------------------------------------------------------------
  22.         //
  23.         // Constructor
  24.         //
  25.         //----------------------------------------------------------------------
  26.        
  27.         /**
  28.          */
  29.         public function MySingleton()
  30.         {
  31.             if( constructorLocked )
  32.             {
  33.                 throw new Error( "MySingleton is a singleton" );
  34.             }
  35.         }
  36.  
  37.         //----------------------------------------------------------------------
  38.         //
  39.         // Public Methods
  40.         //
  41.         //----------------------------------------------------------------------
  42.  
  43.         /**
  44.          */
  45.         public function login( username:String, password:String ):void
  46.         {}
  47.        
  48.         //----------------------------------------------------------------------
  49.         //
  50.         // Getters/Setters
  51.         //
  52.         //----------------------------------------------------------------------
  53.        
  54.         /**
  55.          */
  56.         public static function get instance():MySingleton // read-only
  57.         {
  58.             if( singletonInstance == null )
  59.             {
  60.                 constructorLocked = false;
  61.                 singletonInstance = new MySingleton();
  62.                 constructorLocked = true;
  63.             }
  64.            
  65.             return singletonInstance;
  66.         }
  67.  
  68.     }
  69. }
The unwritten rules of OOP say the class instance should be accessed via a getInstance() method but I find using a getter makes the code a lot cleaner:

ActionScript Code:
  1. MySingleton.instance.login( ... );
Anyway, there you have it.

Reply With Quote  
sentinels sentinels is offline sentinels lives in United States 1 Blog Entries 2007-10-31 #8 Old  
not really an unwritten rule of OOP that says to use 'getInstance'... it's more because not all languages support implicit getter/setter methods, therefore the 'standard' way for singletons is via getInstance() but you can call it kickMe() if you wanted to, it wouldn't really matter.
Reply With Quote  
Thread Tools
Display Modes Rate This Thread
Rate This Thread: