How do I handle a custom event in ActionScript 3? - actionscript-3

I've created an Event Handler/Listener like so:
import flash.events.Event;
public class DanielEvent extends Event {
public var data:*;
public static const APP_STARTED:String = "APP_STARTED";
public function DanielEvent(n:String, data:*){
this.data = data;
super(n)
}
}
Listening to an event using:
addEventListener(DanielEvent.APP_STARTED, appStarted);
Dispatching an event by:
dispatchEvent(new DanielEvent("APP_STARTED", "test"))
And receiving the data by:
private function appStarted(e:Event){
trace(e.data)
}
But I get the error:
Access of possibly undefined property
data through a reference with static
type flash.events:Event.

You have to use your custom event type in the event handler, if you want to access the data property:
private function appStarted(e:DanielEvent): void {
trace(e.data);
}

your event handler is passed a DanielEvent, not an Event:
private function appStarted(e:DanielEvent):void
{
trace(e.data);
}
also. you should also use your constant for your dispatch instead of passing a string, like you've done for your listener:
dispatchEvent(new DanielEvent(DanielEvent.APP_STARTED, "test"));
and don't forget to override clone() if you are planning on dispatching that event more than once.
public override function clone():Event
{
return new DanielEvent(n, data);
}

Related

AS3 CustomEvent not being extended at all?

I get some weird errors when creating CustomEvent, it appears Event being extended does not give access to Event properties:
package
{
import flash.events.Event;
public class CustomEvent extends Event
{
//public static const COMPLETE:String = 'complete';
private var _assetName:String;
public function get assetName ():String
{
return _assetName;
}
public function set assetName ( aname:String ):void
{
_assetName = aname;
}
public function CustomEvent (type:String, bubbles:Boolean = false, cancelable:Boolean = false)
{
super (type, bubbles, cancelable);
}
public override function clone ():Event
{
return new CustomEvent(type, bubbles, cancelable) as Event;
}
}
}
When doing:
myObj.addEventListener(CustomEvent.COMPLETE, objLoaded);
I get error that COMPLETE doesnt exist... Ok, i set it to the place and then it caomplains about cannot convert CustomEvent to Event.
What am i missing here ??
You need to declare this public static const COMPLETE:String = 'complete'; as static var/const are not transfered to extending classes.
The error about converting CustomEvent to Event may be caused by setting event listener to listen to the Event not CustomEvent.
Where is the event dispatched and what does the signature of the listener look like?
We've got a few issues to cover here:
You have your public static const COMPLETE... commented out. Why? That's needed if you want to refer to CustomEvent.COMPLETE as the event type.
Using my psychic third eye, you've got your event listener declared like this:
public completeListener(evt:Event):void
...
That's not going to work the way you want it to. You need
public completeListener(evt:CompleteEvent):Void
...
Unrelated to the compilation issue, your custom event has another issue. Your clone method is not going to clone the assetName property. Try something like this:
public override function clone():Event
{
var ret:CustomEvent = new CustomEvent(type, bubbles, cancelable);
ret.assetName = assetName;
return ret;
}

Flex 4 disptaching custom event from custom component (why flex converting custom event to mouseevent)

This is NOT duplicate of my earlier post (its is slightly different)
But this is similar issue with similar error but its not the same error
The error I am getting now is below while dispatching the custom event from my custom component
TypeError: Error #1034: Type Coercion failed: cannot convert events::MapEvent#a74ab51 to flash.events.MouseEvent.
dispatchEvent(new MapEvent(MapEvent.CLICKED_ON_MAP));
Note: The error in my earlier post is giving below error message
Type Coercion failed: cannot convert flash.events::Event#81ecb79 to com.events.ShopEvent
The difference here are two things, the earlier error is while converting flash event to custom event and now this one is while converting custom event to flash event and secondly, I have no clue why it is trying to convert to the mouseevent where I am just dispatching my custom event with proper listeners.
Can some one correct me what I am doing wrong here.
This is my custome event
package events
{
import flash.events.Event;
import ui.map.MapElement;
public class MapEvent extends Event
{
public static const NEW_ELEMENT_ATTACHED:String = "newElementAttached";
public static const CLICKED_ON_MAP:String = "clickedOnMap";
public static const CLICKED_ON_ELEMENT:String = "clickedOnElement";
public var element:MapElement;
public function MapEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false){
super(type, bubbles, cancelable);
}
override public function clone():Event{
var c:MapEvent = new MapEvent(type, bubbles, cancelable);
c.element = this.element;
return c;
}
}
}
This is how I am dispatching the event from my custom component (WorldMap.as class file)
private function clickHandler(e:MouseEvent):void{
e.stopImmediatePropagation();
trace("worldmap click handler");
if (dragInProgress){
/*trace ("stopping event propagation");*/
dragInProgress = false;
return;
}else{
trace("dispatching proxy click event");
dispatchEvent(new MapEvent(MapEvent.CLICKED_ON_MAP));
}
}
I have declared [Event] metatag as well
[Event(name="newElementAttached", type="events.MapEvent")]
[Event(name="clickedOnMap", type="events.MapEvent")]
[Event(name="clickedOnElement", type="events.MapEvent")]
Finally the listener is attached in other component (controller.as)
_userWorld.addEventListener(MapEvent.CLICKED_ON_MAP,clickedOnWorldMap);
_userWorld.addEventListener(MapEvent.CLICKED_ON_ELEMENT,clickedOnElement);
private function clickedOnWorldMap(e:MouseEvent):void{
_draggingMapElement.hideBaseGrid();
_draggingMapElement = null;
}
private function clickedOnElement(e:MapEvent):void{
}
Its my bad. I fixed the silly bug.
I changed the lister function definition. (Replace mouseevent to MapEvent)
private function clickedOnWorldMap(e:MapEvent):void{
_draggingMapElement.hideBaseGrid();
_draggingMapElement = null;
}

Custom Event not working

I have created a Custom Event, that is fired from a custom component. It should be catched in the main application to change the selectedindex of the viewstack.
But this doesn't work, and I can't figure out why.
This is my Custom Event:
package events
{
import flash.events.Event;
public class ChangeSelectedIndex extends Event
{
public static var index_passed:String = "Index passed";
private var index:int;
public function ChangeSelectedIndex(i:int, type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type,bubbles, cancelable);
index = i;
}
public function get getIndex():int
{
return index;
}
}
}
This is how I fire the event:
protected function checkUsernameExistsDbSucces(event:ResultEvent):void
{
dispatchEvent( new ChangeSelectedIndex(1,ChangeSelectedIndex.index_passed,false,false));
}
And this is my function to catch the event:
private function changeSelectedIndexHandler(event:ChangeSelectedIndex):void
{
mainViewStack.selectedIndex = event.getIndex;
}
In order for your handler to be called when the event is dispatched, you need to add an event listener to your custom component.
myCustomComponent.addEventListener ( ChangeSelectedIndex.index_passed, changeSelectedIndexHandler);
Make sure this line is within the same scope as both your handler function and myCustomComponent, otherwise there will be an error.

Want to send parameters with custom dispatch event

I am creating a library. Here is an example
[Event (name="eventAction", type="something")]
public function create_new_customer(phone_number:String):void
{
-------------;
----;
------------;
rpc.addEventListener(Event.COMPLETE, onCreate_returns);
}
private function onCreate_returns(evt:Event):void
{
var ob:Object = evt.target.getResponse();
dispatchEvent(new something("eventAction"));
}
I have a listener to this event in app side. So when I manually dispatch event I want the
"ob" to be sent as a parameter. How to do it?
You need to create a custom event class with extra properties to pass data with it. In your case you could use a class like
public class YourEvent extends Event
{
public static const SOMETHING_HAPPENED: String = "somethingHappend";
public var data: Object;
public function YourEvent(type:String, data: Object, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.data = data;
}
override public function clone():Event
{
return new YourEvent (type, data, bubbles, cancelable);
}
}
then when yo dispatch you do:
dispatchEvent(new YourEvent(YourEvent.SOMETHING_HAPPENED, ob));
In AS3 you can use DataEvent:
ex:
dispatchEvent( new DataEvent(type:String[,bubbles:Boolean=false,cancelable:Boolean=false, data:String ] );
Instead of example data, I showed the parameters DataEvent takes.
I hope this helps.
Best regards, RA.
Make your custom event carry this ob object. Pass it to the custom event's ctor and voila!

How do I modify existing AS3 events so that I can pass data?

So I want a way to set up events so that I can pass data without creating closures \ memory leaks. This is as far as I have got:
package com.events {
import flash.events.Event;
public class CustomEvent extends Event {
public static const REMOVED_FROM_STAGE:String = "removedFromStage";
public var data:*;
public function CustomEvent(type:String, customData:*=null, bubbles:Boolean=false, cancelable:Boolean=false) {
super(type, bubbles, cancelable);
this.data = customData;
}
public override function clone():Event {
return new CustomEvent(type, data, bubbles, cancelable);
}
public override function toString():String {
return formatToString("CustomEvent", "type", "data", "bubbles", "cancelable", "eventPhase");
}
}
}
This gets me the following behavior:
function testme(e:Event) {
trace(e);
}
test_mc.addEventListener(CustomEvent.REMOVED_FROM_STAGE, testme);
test_mc.dispatchEvent(new CustomEvent(CustomEvent.REMOVED_FROM_STAGE, 42));
//Traces [CustomEvent type="removedFromStage" data=42 bubbles=false cancelable=false eventPhase=2]
removeChild(test_mc);
//Traces [Event type="removedFromStage" bubbles=false cancelable=false eventPhase=2]
My goal is to get the custom data I want to pass to get passed from the event flash fires, not just the one that I fire. For example, what if I wanted to pass a movieclip along with a loader.COMPLETE event to put the resulting bitmap in?
You extended the Event class for it to dispatch with extra data, now if you want the Loader class to dispatch your custom event type, extend the Loader class to do that (or any other class you want to do this with). In this example I'll override URLLoader with this functionality (because Loader actually dispatches events from it's contentLoaderInfo, which needs two overridden classes, and I just want to keep it simple)
package com.net
{
import flash.net.URLLoader;
import flash.events.Event;
import com.events.CustomEvent;
public class CustomLoader extends URLLoader
{
// URLLoader already has a data property, so I used extraData
public var extraData:*;
override public function dispatchEvent(event: Event) : Boolean
{
var customEvent: CustomEvent = new CustomEvent(event.type, extraData, event.bubbles, event.cancelable);
return super.dispatchEvent(customEvent);
}
}
}
Now to use this with your CustomEvent class try this code in your .fla
import com.net.CustomLoader;
import com.events.CustomEvent;
var loader: CustomLoader = new CustomLoader();
loader.extraData = "Extra Data";
loader.load(new URLRequest("test.xml"));
loader.addEventListener(Event.COMPLETE, loadComplete);
function loadComplete(event: CustomEvent) : void
{
trace(event.data); // Extra Data
}
BAM! Custom data on your innately dispatched events!
The following shows the cleanest way to create a custom event. Typically event types have public static references typed in all capitol letters. When an event is dispatched, it passes an Event, or CustomEvent, object to the event handler method. This is where you can retrieve your passed value.
package com.hodgedev.events
{
import flash.events.Event;
public class CustomEvent extends Event
{
public static const VALUE_CHANGED:String = "VALUE_CHANGED";
public var value:Number;
public function CustomEvent(pValue:Number)
{
super(CustomEvent.VALUE_CHANGED);
value = pValue;
}
public override function clone():Event
{
return new CustomEvent(value);
}
}
}
When we dispatch events, we create a new instance of the event to be passed as such.
private var _someValue:int = 12;
dispatchEvent(new CustomEvent(_somevalue));