Flex: NetStatusEvent not fired by Local Shared Object. Why? - actionscript-3

This is what I do: In the 'Local Storage' dialog I set the pointer to 'None' to allow 0 kB. Then I run my code. I get the 'Local Storage' dialog with an [Allow] and [Deny] button. I click [Deny]
The output I get is
2. we are here now
3. adding a handler to the SharedObject
NOTE: The onFlushStatus event handler is NOT called.
I repeat the above stuff, but now click [Allow].
The output I get is the same:
2. we are here now
3. adding a handler to the SharedObject
NOTE: The onFlushStatus event handler is NOT called.
I was using the code from here
Flex: How to detect if user has blocked shared object from writing
Whatever I try (and I tried much), the event handler gets never called on a [Allow] or [Deny] button click. But I want to know which button the user clicked.
var so: SharedObject = null;
var flushStatus: String = null;
so = SharedObject.getLocal('mySpace');
try {
flushStatus = so.flush();
} catch (error: Error) {
trace('1. could not write SharedObject to disk');
}
trace('2. we are here now');
if (flushStatus == flash.net.SharedObjectFlushStatus.PENDING) {
trace('3. adding a handler to the SharedObject');
so.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);
}
public function onFlushStatus(event: NetStatusEvent): void
{
trace('4. in event handler');
}
As suggested I changed my code and added the event listener before calling flush(). Then I run my tests again. Unfortunately my onFlushStatus() is not called.
var so: SharedObject = null;
var flushStatus: String = null;
so = SharedObject.getLocal('mySpace');
trace('0. adding a handler to the SharedObject');
so.addEventListener(NetStatusEvent.NET_STATUS, onFlushStatus);
flushStatus = so.flush();
trace('2. we are here now');
public function onFlushStatus(event: NetStatusEvent): void
{
trace('4. in event handler');
}
The output I get for [Deny]
0. adding a handler to the SharedObject
2. we are here now
The output I get for [Allow]
0. adding a handler to the SharedObject
2. we are here now
The onFlushStatus() is not called.

From this link it appears that so.flush is returning a String with the result of the flush() command. Rather than looking for an event to be fired you should look at the value of the return. If it's a pending then add your event listener and check success/fail.
A good example: here

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.

AS3: Returning value from another function after event happened

Basically I want to check if a user exists in a database using AMF (and that works great!). But then I want to return the boolean value to another function (in another class) that originally called the "checkUserExistance" function. But, since the database connection isn't immidiate, this function will always return a false value (even if "result" is true). So I would like to have the return-line inside the "onUserChecked"-function but that of course gives me an error. I thought I could create an eventListener, but then, the "return userExists"-line would also have to be inside another function, which doesnät work(?)... What can I do?
public function checkUserExistance(username:String) {
var responderBOOLEAN:Responder = new Responder(onUserChecked, onFault)
var userExists:Boolean = false;
connection.connect(gateway);
connection.call("User.checkUser", responderBOOLEAN, username);
connection.close();
function onUserChecked(result:Boolean):void {
userExists = result;
}
return userExists;
}
I'm sorry but you are trying to force an Asynchronous call to a Synchronous one and this is WRONG.
See here
You should learn how to handle events in the correct way.
What can i suggest you that helped me a lot is this
The only true answer here is to save userExists as a member variable, and dispatch event when the server returns you a response. The client side of the things should be similar to:
// add listener, ServerEvent is a custom event (see below)
server.addEventListener(ServerEvent.CHECK_RESPONSE, onCheckResponse);
server.checkUserExistance('username'); // start the query
function onCheckResponse(e:ServerEvent):void {
if (e.userExists) {
}
}
// inside server class
function onUserChecked(result:Boolean):void {
userExists = true;
dispatchEvent(new ServerEvent(ServerEvent.CHECK_RESPONSE, userExists));
}
/* ServerEvent is a custom class that extens Event
Such classes are used so you can pass special properties in them
via constructor (pass data, store it into member variable)
and through getter for that variable.
If you don't like it, simply add/dispatch Event.COMPLETE
and use public property to get userExists from server
*/

closures with popups using flex 4.6

I have this custom event handler that shows a popup and accepts input from the user:
private var mySkinnablePopupContainer:MySkinnablePopupContainer;
private function handleShowGridPopupEvent(event:ShowGridPopupEvent):void {
var mouseDownOutSideHandler:Function = function(mdEvent:FlexMouseEvent):void {
// At this point, event.targetControl contains the wrong object (usually the previous targetControl)
if (mdEvent.relatedObject != event.targetControl) {
mySkinnablePopupContainer.close();
}
}
var gridPopupSelectionHandler:Function = function(popEvent:PopUpEvent):void {
if (!popEvent.commit) return;
// At this point, event.targetData contains the wrong object (usually the previous targetData)
myModel.doSomethingWithData(popEvent.data.selectedItem, event.targetData);
}
if (!mySkinnablePopupContainer) {
mySkinnablePopupContainer = new MySkinnablePopupContainer();
mySkinnablePopupContainer.addEventListener(PopUpEvent.CLOSE, gridPopupSelectionHandler);
mySkinnablePopupContainer.addEventListener(FlexMouseEvent.MOUSE_DOWN_OUTSIDE, mouseDownOutSideHandler);
}
// At this point, event.targetData contains the correct object
mySkinnablePopupContainer.dataProvider = getMyDPArrayCollection(event.targetData);
mySkinnablePopupContainer.open(this);
var point:Point = event.targetControl.localToGlobal(new Point());
mySkinnablePopupContainer.x = point.x + event.targetControl.width - mySkinnablePopupContainer.width;
mySkinnablePopupContainer.y = point.y + event.targetControl.height;
}
Every time the function handler gets called, it will have the correct ShowGridPopupEvent object but by the time it calls the
gridPopupSelectionHandler, it will contain the old object from a previous call. It works the first time, subsequent calls fails.
Somehow the reference to the event object changed somewhere in between before opening the popup and after.
Any idea what am I doing wrong here? Is this a bug with flex?
found the prob. since im attaching listener only once, it will reference the old listener, with the reference to the old data. i guess i was expecting its reference to be updated whenever i create the closure. not in this case. possible fix is to remove the listener and re-add it again but I abandoned the idea of using closures, and aside from what RIAStar mentioned, it is also impractical as it only gives more overhead by creating a new function for every invocation of the handler.

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.

AS3 how to return EventListener value

If I have code that looks like this:
public function getNetStreamPublishClientList():Array
{
var ncStreamListResults = new Object()
ncStreamListResults.onResult = function(list:Array)
{
//this needs to be returned from getNetStreamPublishClientList
return list;
}
this.nc.call("getStreamClientIds",
new Responder(ncStreamListResults.onResult),
this.streamName);
}
how can I return the value of list from getNetStreamPublishClientList?
use global item for list
It looks like you won't be able to know the value of list at the point that getNetStreamPublishClientList() finishes executing.
This is because the nc object will probably not have finished its work by that time, and in that case the completion handler (currently assigned to be onResult) won't have been called.
Whatever is waiting on the result of this function, I'd change it to wait for an event. Possibly use a member function to act as the onResult handler.