Archive for the 'News' Category

27
Jan

Looking for a strong AS3/Flex Engineer to work for a high profile entertainment company in LA

We are looking for a strong AS3/Flex Engineer to work as a contractor for a high profile entertainment company in LA. The job description is listed below:

* General qualities
o Good communication skill
o Reliable
o Must be passionate about programming
o Must be able to work under directions and independently
* Programming languages
o Actionscript 3.0
o Flex 3.0 MXML
o Javascript
+ AJAX (DOM manipulation, XMLHTTPRequest, CSS, DHTML)
o Jquery javascript framework
o Good understanding of XML, XSL, XUL, Xpath, etc.
* Software
o Eclipse
o Flex Builder
o Flash CS3
o ANT
o Subversion

Drop me an email if you are interested.

30
Dec

FlexUnit Asynchronous tests with PureMVC Framework

There are very little resources online in term of how to use FlexUnit with PureMVC and TDD, furthermore in many cases it makes more sense to create the tests after user stories are implemented.

Let’s take the application we created for Cairngorm and convert it to PureMVC framework. This is a good exercise since it can help define the different between the two frameworks.

Creating tests with existing framework may be challenging at times. In fact, there are cases where it’s makes more sense to create the test after the code is completed rather than following common TDD practices.

TDD recommend to create the test before writing the code, however working in real life application and with exsiting frameworks you may find that sometimes it’s easier to write the code before the test, especially when you use plug-ins or code generator scripts to create your user gesture automatically. I recommend to use your own judgment and see what’s works best for you.

Take a look at the post I published yesterday:
http://elromdesign.com/blog/2008/12/29/tdd-and-asynchronous-tests-with-cairngorm-applications/

View application and download the source code:
CairngormPM and TDD

In this example I am using the same FeedsPanelViewer.mxml container I created for the Cairngorm application. However, I made few small change to the container. I decided to remove the binding properties and let the mediator handle all the changes in the container.


<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml"
     layout="vertical"
     width="600" height="450"
     styleName="panelView">

     <!-- Feeds List -->
     <mx:List
          id="feedList"
         change="dispatchEvent(new UserSelectedFeedEvent(FeedVO( feedList.selectedItem )));"
          labelField="title"/>

     <!-- Detail information -->
     <mx:VBox width="540" horizontalScrollPolicy="off" verticalScrollPolicy="off">
          <mx:Spacer height="15" />
          <mx:HBox>
               <mx:Label text="FEED DETAIL:" fontWeight="bold"/>
          </mx:HBox>
          <mx:HBox>
               <mx:Label text="author:" fontWeight="bold"/>
               <mx:Label id="author" width="100%"/>
          </mx:HBox>
     </mx:VBox>

</mx:Panel>

PureMVC Mediator:


package com.elad.TDDPureMVC.view
{
     import com.elad.TDDPureMVC.events.UserSelectedFeedEvent;
     import com.elad.TDDPureMVC.model.FeedsPanelViewerProxy;
     import com.elad.TDDPureMVC.model.vo.FeedVO;
     import com.elad.TDDPureMVC.view.components.FeedsPanelViewer;

     import org.puremvc.as3.interfaces.IMediator;
     import org.puremvc.as3.interfaces.INotification;
     import org.puremvc.as3.patterns.mediator.Mediator;

     public class FeedsPanelViewerMediator extends Mediator implements IMediator
     {
          public static const NAME:String = 'FeedsPanelViewerMediator';

          private var feedsPanelViewerProxy:FeedsPanelViewerProxy;

          public function FeedsPanelViewerMediator(viewComponent:Object=null)
          {
               super(NAME, viewComponent);
               feedsPanelViewer.addEventListener(UserSelectedFeedEvent.USERSELECTEDFEED_EVENT, changeSelectedFeed);
          }

          private function changeSelectedFeed(event:UserSelectedFeedEvent):void
          {
               setDetail(event.selectedFeed);
          }

          public function get feedsPanelViewer():FeedsPanelViewer
          {
               return viewComponent as FeedsPanelViewer;
          }

          override public function listNotificationInterests():Array
          {
               return [
                    FeedsPanelViewerProxy.READ_ADOBE_FEEDS_SUCCESS,
                       ];
          }

          private function setDetail(feed:FeedVO):void
          {
               feedsPanelViewer.author.text = feed.author;
               feedsPanelViewer.category.text = feed.category;
               feedsPanelViewer.description.text = feed.description;
               feedsPanelViewer.link.text = feed.link;
               feedsPanelViewer.pubdate.text = feed.pubdate;
          }     

          override public function handleNotification(notification:INotification):void
          {
               feedsPanelViewerProxy = facade.retrieveProxy(FeedsPanelViewerProxy.NAME) as FeedsPanelViewerProxy;

               switch ( notification.getName() )
               {
                    case FeedsPanelViewerProxy.READ_ADOBE_FEEDS_SUCCESS:
                         feedsPanelViewer.feedList.dataProvider = feedsPanelViewerProxy.feedsCollectionVO.collection;
                         setDetail(feedsPanelViewerProxy.selectedFeed);
                         feedsPanelViewer.title = feedsPanelViewerProxy.panelTitle;

                    break;
               }
          }
     }
}

Proxy:


package com.elad.TDDPureMVC.model
{
     import com.elad.TDDPureMVC.model.vo.FeedVO;
     import com.elad.TDDPureMVC.model.vo.FeedsCollectionVO;

     import mx.rpc.events.FaultEvent;
     import mx.rpc.events.ResultEvent;
     import mx.rpc.http.HTTPService;

     import org.puremvc.as3.interfaces.IProxy;
     import org.puremvc.as3.patterns.proxy.Proxy;

     public class FeedsPanelViewerProxy extends Proxy implements IProxy
     {

          public static const NAME:String = "FeedsPanelViewerProxy";
          public static const READ_ADOBE_FEEDS_SUCCESS:String = 'readAdobeFeedsSuccess';
          public static const READ_ADOBE_FEEDS_FAILED:String = 'readAdobeFeedsFailed';
          public var service:HTTPService;

          public function FeedsPanelViewerProxy()
          {
               super(NAME, new FeedsCollectionVO() );

               service = new HTTPService();
            service.url = "http://rss.adobe.com/en/resources_flex.rss";
            service.resultFormat = "e4x";
               service.addEventListener( FaultEvent.FAULT, onFault );
               service.addEventListener( ResultEvent.RESULT, onResult );
          }

          public function getAdobeFeeds():void
          {
               service.send();
          }

          // Cast data object with implicit getter
          public function get feedsCollectionVO():FeedsCollectionVO
          {
               return data.feedsCollectionVO as FeedsCollectionVO;
          }

          public function get selectedFeed():FeedVO
          {
               return (data.feedsCollectionVO as FeedsCollectionVO).collection.getItemAt(0) as FeedVO;
          }

          public function get panelTitle():String
          {
               return data.panelTitle as String;
          }                    

          private function onResult( result:ResultEvent ) : void
          {
               var feed:FeedVO;
               var item:Object;
               var len:int = result.result[0].channel.item.length();
               var collection:FeedsCollectionVO = new FeedsCollectionVO;
               var dataObject:Object = new Object();

               for (var i:int=0; i<len; i++)
               {
                    feed = new FeedVO();
                    item = result.result[0].channel.item[i];

                    feed.author = item.author;
                    feed.category = item.category;
                    feed.description = item.description;
                    feed.link = item.link;
                    feed.pubdate = item.pubdate;
                    feed.title = item.title;

                    collection.addItem(feed);
               }

               dataObject.feedsCollectionVO = collection;
               dataObject.panelTitle = String(result.result.*[0].*[0]);

               setData(dataObject);
               sendNotification(READ_ADOBE_FEEDS_SUCCESS);
          }

          private function onFault( event:FaultEvent) : void
          {
               sendNotification( READ_ADOBE_FEEDS_FAILED, event.fault.faultString );
          }

     }
}

To test the PureMVC framework I will be using puremvc-flexunit-testing. Our test calls the registerObserver method used for listening for a PureMVC notification on a proxy. We pass the PureMVC view, proxy and information for the AddSync such as the method to send a success response and timeout.


package flexUnitTests.proxies
{
     import com.andculture.puremvcflexunittesting.PureMVCNotificationEvent;
     import com.andculture.puremvcflexunittesting.PureMVCTestCase;
     import com.elad.TDDPureMVC.model.FeedsPanelViewerProxy;

     import flexunit.framework.Assert;

     import org.puremvc.as3.core.View;
     import org.puremvc.as3.interfaces.IView;

     public class ReadAdobeFeedsTestCase extends PureMVCTestCase
     {
          override public function setUp():void
          {
               var facade:ApplicationFacade = ApplicationFacade.getInstance();
               facade.registerProxy( new FeedsPanelViewerProxy() );
          }

          private function get proxy():FeedsPanelViewerProxy
          {
               var retVal:FeedsPanelViewerProxy = ApplicationFacade.getInstance().retrieveProxy(FeedsPanelViewerProxy.NAME) as FeedsPanelViewerProxy;
               return retVal;
          }

          private function get view():IView
          {
               return View.getInstance();
          }

          public function ReadAdobeFeedsTestCase(methodName:String=null)
          {
               super(methodName);
          }

          public function testReadAdobeFeedsEvent():void
          {
               registerObserver(this.view, this.proxy, FeedsPanelViewerProxy.READ_ADOBE_FEEDS_SUCCESS, handleResponse, 300);
               this.proxy.getAdobeFeeds();
          }

          private function handleResponse(e:PureMVCNotificationEvent):void
          {
               Assert.assertEquals("Feed title is incorrect", proxy.panelTitle, "Flex News");
          }
     }
}
22
Oct

New AdvancED Flex 3 book avaliable on Amazon and cover advanced Flex topics

Yesterday APress released the book I co-authored called AdvancED Flex 3. It covers advanced Flex topics such as Ajax, RIA, Web 2.0, Mashups and tons of practical recipes. Jordana, my wife, took an extended break from being an attorney and is doing an amazing job raising our daughter Romi. Without her support, I would not have been able to complete this book. It was pleasure working with Shashank Tiwari, Jack Herrington and Joshua Mostafa.


FACILITATING AUDIO AND VIDEO STREAMING


I showed hands-on techniques for creating a Flex HD video application using Cairngorm. I covered the subject of data layer by designing, configuring, and creating a Microsoft SQL and MySQL database. Creating ColdFusion server side services using best practices to generate services as well as creating custom components to fit the exact needs of the project.

TURBO-CHARGING DATA BINDING


I covered the subjects of explicit and implicit data binding, synchronizing the client model with the server model and binary data objects. I illustrated how to utilize existing plug-ins to create a powerful CRUD applications that can handle processing data and presentation as well as provide fast transmission to the server

FLEX MASHUPS


I showed how to work with Mashup frameworks, dealing with namespaces, interconnectivity and best practices. I covered how to utilize the Web and the enormous amount of resources available, such as: APIs, libraries, custom components, and skins. I showed how to build exciting mashups using some of the most popular APIs such as Yahoo!, Amazon, Flickr, and UMap. I gave tips and tricks on how to start building your own mashup application.

Click here to buy from Amazon!

18
Feb

New advanced flex 3.0 book - Developing Enterprise Architect Applications

I am currently in the process of writing as a co-author in a new book by Apress called: “AdvancED Flex 3″

This book makes advanced Flex 3 concepts and techniques easy. Ajax, RIA, Web 2.0, mashups, mobile, the most sophisticated Web tools and the coolest interactive Web applications are all covered with practical, visually-oriented recipes.

* Practical, how-to approach for advanced results.
* Leverage the tools you know, Java, PHP, Python, Ruby, in combination with Flex.
* Build high-performance Web applications with interactivity that really engages your users

To read more about the book click here.

Additionally, I am in the process of writing the following book:

Advanced Flex 3.0 - Developing Enterprise Architect Applications.
The book will be published in late 2008. The book will cover the subject of developing an Enterprise Level Flex Applications from planning to designing and finally testing. It is intended for the experienced Flex developer wishing to expand his/her knowledge and expertise. Developing a large scale Flex application is different than developing a small application and although there is a lot of information, there is not any one resource that covers it all. This book will cover all the best practices and give you the tools you need to develop such a large scale Flex application.

In the next few months I will be giving away some of the API’s that will be part of the book. To learn more about the book and signup for the pre-order list click here.