Monday, March 1, 2010

Flash / Flex / ActionScript: Using IResponder instead of EventListeners

Using addEventListener is a popular way of of waiting for a response from a server. I've run into issues using this when a server returns the same response for all methods. Many of the listener methods are tripped for the wrong response. The easy way to avoid this is to use an IResponder.

Here is an example using the HTTPService object. You should be able to use the same steps on a method that returns an AsyncToken.

var asyncToken:AsyncToken;
var internalIResponder:IResponder;
...
asyncToken = _httpService.send();
internalIResponder = new AsyncResponder(onHTTPServiceSuccess, onHTTPServiceFault, asyncToken);
asyncToken.addResponder(internalIResponder);

When send is called it will return an AsyncToken. We can attach an IResponder object to the AsyncToken that will handle the success and fail cases for the response.

Labels: , , , , , ,

Thursday, November 12, 2009

Flash / ActionScript 3: Event Bubbling Example

Previously I wrote an article that showed an example of Event Bubbling with Flex. I wanted to write a similar example for ActionScript 3. The principle is the same, but it works just a little different.

Any class involved in bubbling must extend DisplayObjectContainer. Sprite is the most basic DisplayObjectContainer class and most examples I see use it, so that's what I will use. I gave a brief overview of how event bubbling works in the Flex example that I won't repeat here.

I'm creating three classes that include each other. The primary class includes Level1. Level1 includes Level2. Level2 includes Level3. Level3 triggers an event when it's added to the stage. The event from Level3 will bubble through Level2 and Level1 to the primary class without re-dispatching it.

event_bubbling_as.as
package {
    import flash.display.Sprite;
    import flash.events.Event;
    
    import obj.Level1;
    import obj.Level3;

    public class event_bubbling_as extends Sprite
    {
        private var _level1:Level1
        
        public function event_bubbling_as()
        {
            _level1 = new Level1;
            _level1.addEventListener(Level3.EVENT, onEvent);
            
            addChild(_level1);
        }
        
        private function onEvent(event:Event) : void {
                trace('caught event from level 3');
        }
    }
}

Level1.as
package obj
{
    import flash.display.Sprite;
    
    public class Level1 extends Sprite
    {
        private var _level2:Level2;
        
        public function Level1()
        {
            trace("in level 1");
            _level2 = new Level2;
            
            addChild(_level2);
        }
    }
}
Level2.as
package obj
{
    import flash.display.Sprite;
    
    public class Level2 extends Sprite
    {
        private var _level3:Level3;
        
        public function Level2()
        {
            trace("in level 2");
            _level3 = new Level3;
            
            addChild(_level3);
        }
    }
}
Level3.as
package obj
{
    import flash.display.Sprite;
    import flash.events.Event;
    
    public class Level3 extends Sprite
    {
        public static const EVENT:String = "level3";
        public function Level3(){
            trace("in level 3");
            
            //trigger event when the object is added to the stage
            addEventListener(Event.ADDED_TO_STAGE, launchEvent);
        }
        
        public function launchEvent(event:Event) : void {
         var newEvent:Event = new Event(EVENT, true, true);
         dispatchEvent(newEvent);
        }
    }
}
You can download the Flex Project Archive example here. This can be directly imported into Flex. Run it in debug mode to see how each level is triggered.

Labels: , , , , , , , , , , , , , , , , ,

Tuesday, October 13, 2009

Flash / ActionScript 3 / Flex : Reading browser cookies

Part of an ActionScript 3 project I was working on required me to pull cookies from the users browser into Flash. I tried hunting around google to find a good method to achieve this, but found a lot of articles that wanted you to alter the embed code for flash. I wanted to find a way inside Flash to read the users cookies.

I wrote some code to do something similar in ActionScript 2 that used LoadVars. This class has been removed in ActionScript 3.

This is the ActionScript 3 code I came up with. It uses ExternalInterface to execute a bit of javascript that will pull the cookies directly into flash. It alters the cookie string to make it look like a URL and runs it through URLVariables.

package {
    import flash.display.Sprite;
    import flash.external.ExternalInterface;
    import flash.net.URLVariables;
    
    public class BrowserCookies extends Sprite
    {
        //this will parse the cookie data
        private var _urlVariables:URLVariables;
        
        /**
         * Return all the cookie values in one object
         * @return URLVariables 
         * 
         */
        public function get urlVariables() : URLVariables {
            return _urlVariables;
        }
        
        /**
         * Return one cookie value
         * @param value String
         * @return String
         * 
         */
        public function getCookieValue(value:String) : String {
            var returnValue:String = "";
            
            if(_urlVariables && _urlVariables[value]) {
                returnValue = _urlVariables[value];
            }
            
            return returnValue;
        }
        
        /**
         * This will connect to the browser and pull cookies into flash 
         */
        public function BrowserCookies() : void{
            //this will hold the data returned from javascript
            var browserCookieString:String;
            
            //pull the data from javascript
            browserCookieString = ExternalInterface.call("function(){return document.cookie}");
            
            //replace ; with & to make it look like a url
            browserCookieString = browserCookieString.replace(/;\s/g, "&");

            //parse the cookie string into variables. you can now access cookie variables as properties of this object
            if(browserCookieString) {
                _urlVariables = new URLVariables(browserCookieString);
            }
        }
    }
}


Now you can access any cookie property inside flash. Here is a quick example of how to use the class. Assume BrowserCookies.as exists in the same folder as the example class.
package
{
    import flash.display.Sprite;
    import flash.text.TextField;
    
    public class Index extends Sprite{
        public function Index(){
            //this will pull all the cookies out of the browser
            var urlVars:BrowserCookies = new BrowserCookies;
            var textField:TextField = new TextField;
            
            textField.width = 200;
            textField.height = 200;
            textField.text = urlVars.getCookieValue("today");
            
            addChild(textField);
        }
    }
}

I've uploaded a Flex Projext Export version of this example available here. Feel free to contact me if you have any questions.

Labels: , , , , , , , , , , , ,

Flash / Actionscript 3: DataFormat doesn't exist

I was looking through the ActionScript 3.0 Cookbook today and started experimenting with the URLLoader class. The example on page 437 talks about setting the format for the incoming URL. When setting the dataFormat property of URLLoader it suggests using the constant called DataFormat. The only problem is this constant doesn't exist. It's a typo.

The real value is called URLLoaderDataFormat. You can read more about it here.

Labels: , , , , , , , ,