The other day, my colleague (Ajit Parthan) was telling me about a wierd behavoiur he had noticed with the Alert.show() in flex. In flex, when you throw an alert, the code execution doesnt halt.
I have myself noticed many times that when you give out multiple alerts, each alert popups one over the other. Each alert doesnt wait for the user to manually dispose it before proceeding further with the code. Is that wierd? Somehow, it never ‘clicked’ to me that this could be problem
. But, now I relealized that it could be a slight inconvenience. That is, it requires the developer to do things a bit differently than he is used to in other languages.
In javascript or java, when the user alerts in the code, the code execution stops after popping up the alert. And when the user clicks OK, then the execution continues. Since apparently this was not happening in Flex, Ajit went looking around for the solution and this is what he found.
It isn’t a bug; it’s due to the way that the Flash Player works. The Player isn’t threaded and doesn’t have public APIs for processing its event queue. Alert.show() must return as soon as the Alert is shown — not when the user dismisses it — so that the Player can handle the user’s mouse and keyboard events while the Alert is up.
This is similar to what happens when you use APIs that load information over the network… they return immediately, and you get notified via an event when the data arrives.
- Gordon Smith (in Flexcoders mailing list)
To handle this, you have to write a handler function to be executed if the user clicks OK, and pass it as an arguement to the Alert.show() method. For example, if you are trying to save some user info to the backend, and you would like the user to confirm the action.
alert("Are you sure?", "Confirmation", mx.controls.Alert.OK | mx.controls.Alert.CANCEL, setUserInfo);
In the code above, the setUserInfo function will be called if the user clicks on OK. For more details, check out here and here.



Didn’t you notice, that popup messages appear in reverse order : the first Alert.show in Actionscript is the last one that the user can validate because the follower Alert have been opened on top of it.
Other strange behavior, is that the Alert.show does not not popup until the execution of the Actionscript code is complete (try a while loop just after the Alert.show to check this behavior).
Yepp. You are right. Typically, when u have 3 alerts executed one after the other -
Alert.show (“1″);
Alert.show (“2″);
Alert.show (“3″);
1 gets thrown. Then, the script goes down and throws 2. Now, the screen already has 1, so 2 gets loaded below 1 and then 3 gets loaded below 3. The second point u mentioned – I haven’t noticed it till now
. I’ll check it out.
This has been a real challenge, and if any of you have solved it, I would be most appreciative. I need for the code to STOP EXECUTING while I query my user if he really wants to abandon changes made:
1) User selects a movie title from a ComboBox
2) Initialize on ComboBox sets up a watcher on “selectedTitle”
3) Close on ComboBox:
a) Checks to see if the user changed any content
b) If so, Alert.show of the “wanna save your changes? Y/N” variety
c) In either case, changes value of selectedTitle to new title
4) Upon change of selectedTitle, the watcher is triggered and the
user gets a choice of different content about the title.
Problem is, that dratted alert does not display until AFTER the user has not only changed the title, but selected the new content…by which time the user is now focused on the new info and a message to him about “hey buddy, wanna save the content from the previous title? You made some changes, there!” is just inelegant and confusing.
Any ideas???
[...] Comprendre le comportement des mx.controls.Alert quand vous en utilisez plusieurs. [...]
private function firstFunction():void {
mx.controls.Alert.show(“Are you sure you want to change the status?”,”Warning”, Alert.OK | Alert.CANCEL, this, alertListener, null, Alert.OK);
}
private function alertListener(eventObj:CloseEvent):void {
// Check to see if the OK button was pressed.
if (eventObj.detail==Alert.OK) {
//do something that they agreed to.
}
//do nothing (cancel)
}
Lisa,
I’m late to the party, but I’ll share my solution to a similar problem; it might come in handy for other wanderers who find this discussion.
Your problem boils down to the fact that the watcher fires an event only after the change has taken place. What you will likely need to do is to create a custom ComboBox and override the selectedTitle setter. Something like this:
override public function set selectedTitle(value:TitleClass):void {
if (userChangedSomeContent()) {
Alert.show("You changed stuff. Save changes?","Save Dialog", Alert.YES | Alert.NO, this, function(evt:CloseEvent) {
if (evt.detail == Alert.YES) saveChanges();
_selectedTitle = value;} );
} else { _selectedTitle = value; }
}
The important bit is the anonymous function created in the fifth parameter of the Alert.show() call. Because _selectedTitle is set within the handler function, execution is effectively halted until the user makes a choice. I’m not a huge fan of doing it this way because it makes it very hard to debug. I do not know a way to pass “value” as a second parameter to a separately-declared CloseEvent handler function, though.
In order for this to work correctly, you must have a private variable _selectedTitle that you’ll access using the above set function and a simple getter function.
I found another solution. Its still messy but it beats having to add in a private variable just to move your parameters around.
The Alert.show() method won’t let you pass additional parameters to the closeHandler, but you can get around it by defining your handler function inline. Here is an example:
public function myAlertFunction(myParam:Number):void
{
Alert.show(…,function(event:CloseEvent):void{
//do your handler logic here
myParam=2;
},…);
}
If your close handler logic is too unwieldy to cram into an inline function then move it back into a seperate handler and call that from your inline function instead.