Can not fire a event from a Polymer 3 Mixin - polymer

I have the below in a mixin. However, dispatchEvent is not attached to this. I get the error Cannot read property 'dispatchEvent' of undefined.
So, I used window.dispatchEvent instead but the event doesn't get caught by the parent element. Any ideas what I can do to fire a event in a mixin?
fetchError(response) {
...
this.dispatchEvent(new CustomEvent(
'http-error', {bubbles: true, detail: msg, composed: true}
));
return Promise.reject(new Error(response.statusText));
}

You probably need to bind the method
Add this to your mixin:
constructor() {
super();
this.fetchError = this.fetchError.bind(this)
}

Related

How to know if the triggered events succeed or fail in Yii2

I trigger an event in Yii2 transaction, and I want to know if the event handler succeed to commit the transaction, or fail to rollback.
Is a global variable or class const the right way?
What I do now is throwing an error in the event handlers.
Usually you're using event object to store state of event. Create custom event:
class MyEvent extends Event {
public $isCommited = false;
}
Use it on trigger and check the result:
$event = new MyEvent();
$this->trigger('myEvent', $event);
if ($event->isCommited) {
// do something
}
In event handler you need to set this property:
function ($event) {
// do something
$event->isCommited = true;
}
If you want to break event flow you may use $handled property instead of isCommited and custom event.

nested function cant find itself in Typescript

I have the following code:
//Main Entry Point.
start() {
this.init();
this.gameLoop();
}
//Init, runs only once.
init() {
let initalEntity1: Entity = new Entity(10, 10, Gender.female);
let initalEntity2: Entity = new Entity(60, 60, Gender.male);
console.log("There are " + this.Entities.length + " Items in the entities Array")
this.Entities.push(initalEntity1, initalEntity2);
console.log("There are " + this.Entities.length + " Items in the entities Array")
}
gameLoop() {
console.log("Performing a Game Loop");
requestAnimationFrame(this.gameLoop);
//MAIN LOOP THROUGH ENTITIES
for (let i in this.Entities) {
this.Render.drawEntitysToScreen(this.Entities[i].EntityPosition, this.Entities[i].gender);
}
}
It enters into start() fine, and also performs all of the init() functionality. it them proceeds onto gameloop() which it will run once, however the line requestAnimationFrame(this.gameLoop); which is ment to retrigger the function to be called as a Canvas frame is causing the following error:
TypeError: this is undefined
trying to requestAnimationFrame(gameLoop); but it causes the typescript compiler to get upset...
This is due to how this binding works in javascript. The way by which you are passing this.gameLoop to requestAnimationFrame is essentially passing an unbound gameLoop function, and so when it is called, it has lost reference to its this.
There are a number of possible solutions to this problem:
You can bind this.gameLoop to this inside of the class constructor, like so:
constructor() {
this.gameLoop = this.gameLoop.bind(this);
}
You can bind this.gameLoop to this as part of the gameLoop method definition. Rather than defining gameLoop like
gameLoop() {
If you instead use
gameLoop = () => {
it will be automatically bound to this. This is a property of using the fat arrow for function declarations: it automatically performs binding to the this that exists at the function declaration.
You can change how you pass gameLoop to requestAnimationFrame:
requestAnimationFrame(() => this.gameLoop());
This again takes advantage of the automatic this binding performed by the arrow function, but instead of doing it as part of the class method declaration you can simply do it lazily at the time you need it to be bound.
Note, however, that doing it this way does mean that a new function will be created each time gameLoop is called.
When you call this.gameLoop() within start, the value for this inside gameLoop's body will be the class gameLoop belongs to, because you call gameLoop as a property of this (the class).
When you pass a function reference its value for this might be anything when the function is called from somewhere else.
Solution 1 | Using Function.prototype.bind
bind the value for this as you give the function to requestAnimationFrame. By doing this you explicitly say:
Let the argument to bind be this inside any call to gameLoop, regardless of how it is called, or where it is called from.
requestAnimationFrame(this.gameLoop.bind(this));
Note that bind returns you a new function, so the original gameLoop function that is still a property of your class remains unchanged.
Solution 2 | Using an arrow function
Define an arrow function to eventually execute the call to gameLoop instead of requestAnimationFrame. The this value within arrow functions is static, and is inherited from the execution context enclosing the function declaration.
requestAnimationFrame(() => this.gameLoop());

AS3 passing a callback function into a class constructor for use with addEventListener

This has been bugging me for a few days now. I have written a multi-functional messageBox class, and it works pretty well, but there's one thing I'm stuck on. First, though, here's some code:
in the document class I have:
var tMsg:Msg = new Msg("Test Message", "This is a test Message", Msg.INPUT);
tMsg.addEventListener('Answered', qa, false, 0, true);
function qa(e:Event):void{
trace(e.target.label,e.target.result);
tLabel.label = e.target.result;
}
When either the 'cancel' or 'ok' buttons are clicked, the result property is set and the 'Answered' event is dispatched. Since this event listener will always need to be added, I thought it would be better to include it within the class constructor; however, each instance of the Msg class would need its own callback, depending on what the result is being used for. Also, the callback functions should be declared in the document class.
I thought this could be accomplished by simply passing the function to the Msg class constructor, and then use that reference to generate the addEventListener dynamically.
For example:
/// in document class
var tMsg:Msg = new Msg("Test Message", "This is a test Message", Msg.INPUT, qa);
function qa(e:Event):void{
trace(e.target.label,e.target.result);
tLabel.label = e.target.result;
}
/// in Msg class
public function Msg(txt:String='', msg:String='', type:String=ALERT, callback:Object=null) {
_callback = callback;
addEventListener(Event.ADDED, setup, false, 0, true);
}
private function setup(e:Event){
stage.addEventListener('Answered', _callback, false, 0, true);
}
This doesn't work. I don't know if it's because I'm trying to store the callback reference (the event listener should be added to the stage object) or what? The upside to getting this to work would be I wouldn't have to add an event listener each time I create a new message, just pass along the associated function.
Thank you in advance for any help you could provide me.
You should add the event listener to the object that dispatches the event. If that object isn't on the display list or the event doesn't bubble then the stage will not receive the event.

Flex event handler not working

I have created a custom event in flex 3.5. But the handler is not invoked. How to solve this or what is the way to debug this problem?
The Event class:
package com.saneef.worldlanguages.events
{
import flash.events.Event;
public class LanguageEvent extends Event
{
public static const LANGUAGE_SELECTED:String = "LanguageSelected";
public function LanguageEvent(type:String,languageid:String)
{
super(type);
this.langid = languageid;
trace("LanguageEvent: " + this.langid);
}
public var langid:String;
override public function clone():Event {
return new LanguageEvent(type, langid);
}
}
}
Dispatching:
private function functionOne():void
{
try{
dispatchEvent(new LanguageEvent(LanguageEvent.LANGUAGE_SELECTED,"STR"));
}
catch(e:Error)
{
trace(e.message);
}
}
In the Main application class, EventListener:
protected function application1_initializeHandler(event:FlexEvent):void
{
this.addEventListener(LanguageEvent.LANGUAGE_SELECTED,
application1_LanguageSelectionHandler);
}
The event handler function:
public function application1_LanguageSelectionHandler(event:LanguageEvent):void
{
trace("application1_LanguageSelectionHandler: " + event.langid);
populate_countrya3id_languages(event.langid);
}
Your code looks fine. Since I can't see the full source, here are my two thoughts on what may be going on:
Are you sure your addEventListener call is done before you dispatch the event? Add some trace to make sure the application1_initializeHandler prints before functionOne does.
Is your functionOne call in another different component than your main application? If so, you'll need to set your custom event's bubbles attribute to true in your event's super call.
public function LanguageEvent(type:String,languageid:String,bubbles:Boolean=True)
{
super(type, bubbles);
this.langid = languageid;
trace("LanguageEvent: " + this.langid);
}
See the flash.events.Event docs for the constructor call. Also, here's a quote about the bubbles argument explained here:
The bubbles property
An event is said to bubble if its
event object participates in the
bubbling phase of the event flow,
which means that the event object is
passed from the target node back
through its ancestors until it reaches
the Stage. The Event.bubbles property
stores a Boolean value that indicates
whether the event object participates
in the bubbling phase. Because all
events that bubble also participate in
the capture and target phases, any
event that bubbles participates in all
three of the event flow phases. If the
value is true, the event object
participates in all three phases. If
the value is false, the event object
does not participate in the bubbling
phase.
Based on your source code, it looks like you've seen the "Dispatching Custom Events" in the flex docs, but I'll link to it anyways for future/easy reference: http://livedocs.adobe.com/flex/3/html/help.html?content=createevents_3.html.
Also, check out http://www.adnandoric.com/2008/12/29/understanding-the-flex-event-propagation/ for a high-level overview of the event propagation system to try to get a better understanding of what's going on while developing.
Edit:
Based on your comments I'm guessing your functionOne call is in a separate class and your "main" application has an instance of this class. If that's so you'll want to attach your event listener on that instance and delegate it to your main's application1_LanguageSelectionHandler function... Like so:
protected function application1_initializeHandler(event:FlexEvent):void
{
this.theInstanceThatHoldsYourFunctionOne.addEventListener(LanguageEvent.LANGUAGE_SELECTED,
application1_LanguageSelectionHandler);
}

Is there a way for listening for changes in flash.display.DisplayObjectContainer numChildren property?

I want to run some code whenever a DisplayObject is added as a child to a DisplayObjectContainer.
Or to put in other words, to catch the addedToStage event of all DisplayObjects, even ones I don't know about.
Is it possible? and if not, any ideas on how to do something similar?
An 'added' event is dispatched whenever a child display object is added to the display list via addChild() or addChildAt(). In the DisplayObjectContainer class add the listener:
addEventListener(Event.ADDED, onAdded);
and the handler:
private function onAdded(e:Event):void
{
trace('number of children is now ' + numChildren);
}
Using Event.ADDED_TO_STAGE on stage Object and setting useCapture to true.
More info on event here
Example:
function onAdded(e:Event):void{
trace(e.target.toString()); //use target to get the Object added
}
stage.addEventListener(Event.ADDED_TO_STAGE, onAdded, true); // set capture to true
I don't know if there is a built in way to do this.
Alternatives include the obvious,
private var _num_children:Number = 0;
addEventListener(Event.ENTER_FRAME, _checkChildren, false, 0, true);
private function _checkChildren($evt:Event):void {
if (this.numChildren != _num_children) {
_num_children = this.numChildren;
// There was a child (or more) added in the last frame execution
}
}
However, this seems like a more elegant solution...
public function _addChild($do:DisplayObject) {
$do .addEventListener(Event.ADDED_TO_STAGE, _childAdded);
addChild($do );
}
private function _childAdded($evt:Event) {
// do whatever with $evt.target
}
The difference here, is the _childAdded will get fired for each and every child added via _addChild method. This means if you are doing some costly code execution you will be doing it once for each child instance.
If you use the first method, you are only calling the method once per frame, and if 10 images are added on a single frame, then it will only run once.