Archive for the ‘Flex’ Category

HTTPService request via proxy

April 29, 2012

I am working on this side project in Flex that I need to use PHP and curl (code is very similar to this) to delegate my http calls to some RESTful services. While I debug it from Flash Builder IDE, everything works fine; but when I put my release build to the server, I get the following errors:

[RPC Fault faultString="HTTP request error" faultCode="Server.Error.Request" faultDetail="Error: [IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032: Stream Error. URL: http://localhost:37813/views/INLINE/rows.json?accessType=API&method=clustered2&min_lon=-89.761262&min_lat=41.700473&max_lon=-85.806184&max_lat=42.294452&target_node_clusters=250&min_distance_between_clusters=0.005188813084372479&https=Y%5D. URL: https://data.cityofchicago.org/views/INLINE/rows.json?accessType=API&method=clustered2&min_lon=-89.761262&min_lat=41.700473&max_lon=-85.806184&max_lat=42.294452&target_node_clusters=250&min_distance_between_clusters=0.005188813084372479"]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:345]
at mx.rpc::Responder/fault()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\Responder.as:68]
at mx.rpc::AsyncRequest/fault()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:113]
at DirectHTTPMessageResponder/errorHandler()[E:\dev\4.y\frameworks\projects\rpc\src\mx\messaging\channels\DirectHTTPChannel.as:410]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/onComplete()

To debug, I went back from the very beginning and tested my DAO interfaces one method after another until I nailed down to the following error. The reason is that requests through an HTTPService through the aforementioned proxy with its headers property specified will trigger the following sandbox violation (Flash Player 11.2.202).

myHTTP.headers = {Accept: "application/json"};
or
var header:Object=new Object();
header["Accept"] = "application/json";
myHTTP.headers = header;

[RPC Fault faultString="Security error accessing url" faultCode="Channel.Security.Error" faultDetail="Destination: DefaultHTTP"]
at mx.rpc::AbstractInvoker/http://www.adobe.com/2006/flex/mx/internal::faultHandler()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\AbstractInvoker.as:345]
at mx.rpc::Responder/fault()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\Responder.as:68]
at mx.rpc::AsyncRequest/fault()[E:\dev\4.y\frameworks\projects\rpc\src\mx\rpc\AsyncRequest.as:113]
at DirectHTTPMessageResponder/securityErrorHandler()[E:\dev\4.y\frameworks\projects\rpc\src\mx\messaging\channels\DirectHTTPChannel.as:437]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.net::URLLoader/redirectEvent()

As my proxy already specifies the headers of my calls (‘Accept: application/json’,  ‘Content-type: application/json’,  “X-App-Token:XXXxxxxXX”), there doesn’t seem a need to specify this headers property for any HTTPService used in Flex at all.

Advertisements

Modular flex (4) applications 101

March 27, 2011

How to use modules in the same project:

  1. Define an interface for your module as the following. The whole point of modular app is to program to abstract interfaces so that different parts of your app have less dependency on one another; it also makes it easier to test:package
    {
    import flash.events.IEventDispatcher;
     

    public interface IInnerModuel1 extends IEventDispatcher
    {
    function foo():void
    }
    }

  2. Create a new module by right-click on the project on the Package Explorer> New > MXML Module.  Flex then generates a spark module (s:Module) for you. The module can has its own namespace; if it does, that means the resulting .swf file will be compiled into a subfolder that corresponds to its namespace structure, like  “/debug-bin/com/mh/test/flex/modules/MyInnerModule1.swf” or something.<s:Module xmlns:fx="http://ns.adobe.com/mxml/2009"
    xmlns:s="library://ns.adobe.com/flex/spark"
    xmlns:mx="library://ns.adobe.com/flex/mx"
    implements="IInnerModuel1">
     

    <fx:Script>
    <![CDATA[
    public function foo():void
    {
    myFooLabel.text = "Yo! What's up?";
    }
    ]]>
    </fx:Script>
    ...

    </s:Module>

  3. Add the module to the project by right-click  > Project Properties > Flex Modules > Add and navigate to the .mxml or the .as component.
  4. Load the module for the main app to use. You can do this using the following tag in your main app:
    <s:ModuleLoader id="innerModule1Loader" url="com/mh/test/flex/modules/MyInnerModule1.swf" />
  5. In order to access your module from main WindowedApplication, you can do this:protected function button1_clickHandler(event:MouseEvent):void
    {
     

    if(innerModule1Loader.child == null)
    return;

    var iChild:* = innerModule1Loader.child as IInnerModuel1;
    iChild.foo();

    }

Some links:
How to pass data to modules and access modules from main app and vice versa (Flex 4)

How to use modules from different Flex projects

Step by step of how to use modules in Flex 3

 

Passing on complex object when declaring an ActionScript/MXML component

March 26, 2011

If you want to configure a complex object and pass it on to an ActionScript component when declaring the component, you can use the default property for the latter to pass in the former. Here:

//actionscript
package com.adobe.login.control
{
...
[DefaultProperty("handlers")]
public class SimpleController extends UIComponent
{
[ArrayElementType("com.adobe.login.control.handler.Handler")]
public var handlers : Array;

public function SimpleController()
{
addEventListener( FlexEvent.INITIALIZE, handleInitialize );
}

private function handleInitialize( event : FlexEvent ) : void
{
for( var i : int = 0 ; i < handlers.length ; i++ )
{
var handler : Handler = Handler( handlers[i] );
parent.addEventListener( handler.eventId, handler.execute );
}
}
}
...
}

// mxml
<mx:Application ...
...
<mx:Script>
<![CDATA[
...
[Bindable]
private var pm : MainPM = new MainPM();

]]>
</mx:Script>

<control:SimpleController>
<handler:LoginHandler
client="{ pm }"/>
</control:SimpleController>
...

Access main window application (top-level application) in Flex 4/AIR 1.5

March 6, 2011

Sometimes you need to access the top-level/main application (in terms of AIR desktop, it would be the main window, a.k.a the s:WindowedApplication instance that you set as “Default Application” under the default package) directly from your object. The reason for this could be that you have some sort of window manager that you roll out by your own that resides in the “default application” which manages all the windows in your application. You can communicate with the window manager via some event mechanism, or simply directly send a message to it from within your window object, like this:

FlexGlobals.topLevelApplication.windowManager.closeWindow(this);

FlexGlobals and topLevelApplication work on Flex 4, AIR 1.5 and Flash Player 10.

Flex compiler: Keep generated ActionScript

November 12, 2010

Project properties -> Flex Compiler -> Additional compiler arguments ->

Add “-compiler.keep-generated-actionscript” (without quotes)

Here:

List of Flex Compiler ArgumentsUnderstanding Flex Compilers

Data binding 101 (flex gumbo)

September 19, 2010
  • Data binding is the plumbing (or “out-of-the-box” feature) provided by modern presentation frameworks such as Flex SDK and WPF. The general idea is to facilitate communications concerning value changes among different objects, so that the application developers can focus on higher level tasks. Most of these plumbings are optimized for declarative code (MXML, XAML and metadata tags in your procedural code). For example, if you use [Bindable],<fx:Binding> meta tags or curly braces (MXML data binding expressions), Flex compiler will give compilation warnings about whether it thinks the data bindings you set up will work nor not; while you don’t get this kind of nice friendly reminder if you use mx.binding.utils.BindingUtils or mx.binding.utils.BindingUtils.ChangeWatcher directly.
  • Data binding is nothing magical than using event listeners to watch for changes on objects/values and then get the updated values. There are two sides of the equation:A. You tell the compiler which object/value you’d like to watch, like so:[Bindable(event="selectedEmployeeChanged")]
    public function get selectedEmployee():Employee
    {
    return _selectedEmployee = v;
    }

    Here you tell the Flex to get the value for _selectedEmployee whenever the interested parties are notified by the event “selectedEmployeeChanged”.  If you don’t specify an event name, flex will automatically associate this data bound value with an event named “propertyChange” and will dispatch that event for you behind the scene. This is convenient for the developer as you don’t need to care about when to fire the event(s) and which event(s) you need to listen for the involved parties, etc..

    B. You tell the compiler when the object/value is changed, like so:
    public function set selectedEmployee(v:Employee)
    {
    if(!v.equals(_selectedEmployee))
    {
    _selectedEmployee = v;
    dispatchEvent(new Event("selectedEmployeeChanged", true, true));
    }
    }

    Here you trigger the data binding (chain) by firing the “selectedEmployeeChanged” event which you defined in step A. Flex then will copy the values for you to the interested parties (destinations of the data binding.)

  • To really understand data binding, it’s important to understand under what conditions the compiler will do the work for you (or the opposite, “when data binding is not supported”) when you set up your data binding (using <fx:Binding>, [Bindable] and data binding expressions). It helps to give examples to show when it doesn’t work. Scenario: You want to watch property changes in another class. For example, if I have an object called FacebookStatus and it contains properties such as numberOfLikes and numberOfDislikes (a feature pending further proof by the product manager) and I have another object called UserInfo which contains a FacebookStatus object. If my FacebookStatus object wants to watch changes of numberOfLikes of FacebookStatus, I can’t simply say:
    <!--In FacebookStatus-->
    public function set numberOfLikes(v:int)
    {
    _numberOfLikes = v;
    dispatchEvent(new Event("statusChange"));
    }

    <!--In UserInfo-->
    [Binding(type="statusChange", type="flash.events.Event")]
    public function handleUserStatusChange(event:Event):void
    {
    //do something to react...
    }

    In the example above, UserInfo will never gets notified by “statusChange” as the compiler won’t look into another object to make the [Binding] tag work. In this case, you can do the binding work yourself by using mx.binding.utils.BindingUtils.bindSetter().
  • It helps to understand what the data binding doesn’t do as well as the trade-offs of having the compiler doing the data binding for you. Sometimes it’s better to do the work yourself. For example, if you have a Watch object that works somehow like a timer (stores information about the minutes elapsed since certain point of time) and you want to show it on the screen, you have to call a function to constantly get the minutes value (e.g., in a loop) in order to get the UI updated constantly. Merely setting up the data binding from the Watch object to the UI is not sufficient.Also, since the compiler needs to create a lot of listeners under the hook, it can consume much more memory and involves deep function stack calls to eventually get the values copied around.
  • If you set up your data binding in <fx:Binding> tags or using [Bindable] metadata tags, Flex sets up the data binding at the “initialization” stage of the UIComponent’s life cycle. It uses try/catch to hide the null objects/values errors and update the values when available.
  • If you have a data object with complex properties, which has complex properties, etc., (e.g, employee.supervisor.department.id) and you want to data bind it’s property, then each node in the data binding chain needs to be set up as data bindable. This won’t automatically happen; but the compiler will give a friendly warning about it if it finds any of the properties in the chain is not data bound.
  • You can watch for more than one event on a value change:[Bindable("change")]
    [Bindable("valueCommit")]
    public function get selectedIndices():Vector.<int>
    {
    return _selectedIndices;
    }

Here are several interested read (last one in Chinese):
Two-Way Data Binding in Flex 4
Michael Labriola’s presentation entitled Diving in the Data Binding Waters
Flex 数据绑定易犯的错误:普遍的误用和错误

Custom (spark) item renderer and component

September 13, 2010

For whatever reason, you want to extend UIComponent (or any of the subclasses) or ItemRenderer, you can do it in either ActionScript or MXML.

In ActionScript, you do it like this:

//class definition. The file name is "MyItemRenderer.as"
public class MyItemRenderer extends ItemRender {//stuff here...}

In MXML, you do it like this:

<?xml version="1.0" encoding="utf-8"?>
<!--The base class is the top tag. The file name is  "MyItemRenderer.mxml"-->
<mapping:BaseMarker xmlns:fx="http://ns.adobe.com/mxml/2009" ...>...</mapping:BaseMarker>

Flex automatically generates an ActionScript class of the same name as your .mxml file name when you compile.

If you extend your ItemRenderer or UIComponent subclass using MXML, you can do the same things as you extend them using ActionScript, such as assign a property, or override a protected or public member. It’s often obvious how you override the methods, as these happen in the <s:Script> block(s). It took me a while to get used to the fact that I can simply assign properties (public var in ActionScript) right on the top tag (where you declare the base class/tag).

Below is an example: The idea was to use a base marker used for a map and then have different flavors of markers; but in the real project, I decided I would rather use different itemRenderers instead of subclassing the base one, as the latter seems more convenient for the scope of the project.

<!–base marker: BaseMarker.mxml–>

<?xml version=”1.0″ encoding=”utf-8″?>
<s:ItemRenderer xmlns:fx=”http://ns.adobe.com/mxml/2009&#8243;
xmlns:s=”library://ns.adobe.com/flex/spark”
xmlns:mx=”library://ns.adobe.com/flex/mx”
autoDrawBackground=”true”>
<fx:Script>
<![CDATA[
import com.mh.mapdispatch.model.Location;
[Bindable]
public var iconSource:Class;
[Bindable]
public var labelText:String = “”;
[Bindable]
public var displayLabel:Boolean = false;
[Bindable]
public var labelColor:uint = uint(“0x000000”);
[Bindable]
public var labelBorderColor:uint = uint(“0x000000”);
[Bindable]
public var labelBackgroundColor:uint = uint(“0xffffff”);

private var _latitude:Number;

[Binable]
public function get latitude():Number
{
return _latitude;
}
public function set latitude(value:Number):void
{
_latitude = y = value;
}

private var _longitude:Number;
[Binable]
public function get longitude():Number
{
return _longitude;
}
public function set longitude(value:Number):void
{
_longitude = x = value;
}

]]>
</fx:Script>
<!– Flex data binding will not able to detect assignments to latitude/longitude
<fx:Binding source=”latitude” destination=”y” twoWay=”true”/>
<fx:Binding source=”longitude” destination=”x” twoWay=”true”/>
–>
<s:VGroup>
<mx:Image id=”markerIcon” source=”{iconSource}”/>
<s:BorderContainer id=”labelBorder”
visible=”{displayLabel}”
includeInLayout=”{displayLabel}”
borderColor=”{labelBorderColor}”
backgroundColor=”{labelBackgroundColor}”>
<s:Label id=”markerLabel”
text=”{labelText}”
color=”{labelColor}”/>
</s:BorderContainer>
</s:VGroup>
</s:ItemRenderer>

<!–subclass itemrenderer: CameraMarker.mxml–>

<?xml version=”1.0″ encoding=”utf-8″?>
<mapping:BaseMarker xmlns:fx=”http://ns.adobe.com/mxml/2009&#8243;
xmlns:s=”library://ns.adobe.com/flex/spark”
xmlns:mx=”library://ns.adobe.com/flex/mx”
xmlns:mapping=”com.mh.mapdispatch.infrastructure.mapping.*”
autoDrawBackground=”true”
displayLabel=”true”
labelText = “{data.location}”
latitude = “{data.location.latitude}”
longitude =”{ data.location.longitude}”>
<fx:Script>
<![CDATA[
override public function set latitude(value:Number):void
{//do stuff here…}
]]>
</fx:Script>
</mapping:BaseMarker>

This one is pretty interesting, in terms of how to use MXML to create itemRenderers.

Flash Builder not creating .html wrapper file

July 10, 2010

This morning Flash Builder 4 (SDK 4.1.0) kept saying “File not found: ….. *html”, which is the html wrapper for the app. Here is how I fixed it:

  1. Project properties->Flex Compiler->HTML wrapper->Uncheck “Generate HTML wrapper file”->OK;
  2. Build project;
  3. Check “Generate HTML wrapper file” in step #1->OK;
  4. Build project.

MVVM: Take One

June 26, 2010

I am wrapping my head around MVVM (Model-View-ViewModel) these days. Although I am a totally newbie to .NET, I’ve found it a very good thing to relate it to my experience with Flex SDK, as it gives me a deeper understanding about the thinking behind UI development. John Gossman from Microsoft has an awesome article about “MVVM“; Paul Williams from Adobe also has an awesome article about “Presentation Model“. Here is Martin Fowler’s article about “Presentation Model” that Paul refers to.

“ViewModel could be seen as a specialized aspect of what would be a Controller (in the MVC pattern) that acts as a data binder/converter that changes Model information into View information and passes commands from the View into the Model. The ViewModel exposes public properties, commands, and abstractions. The ViewModel has been likened to a conceptual state of the data as opposed to the real state of the data in the Model.” Basically ViewModel is a specialized representation of Model that is designed to manipulate View in a way that’s more friendly to the user mental model of the data (or in another word, how the UI is presented). Changes in the properties of ViewModel and changes in View are coordinated via data binding, mostly conveniently done declaratively.  These kind of “out-of-the-box” plumbings of Flex and WPF have freed the developers from having to deal with lower level of View manipulation using code, instead help them to focus on thinking in terms of user mental model, application flow and user interaction. There is this statement that ViewModel and View are completely decoupled, which I don’t agree. ViewModel is an adapter from the Model to the View; If the UI or user flow changes, the ViewModel has to change accordingly. Say you are building a “shopping cart” app for books that’s used on a small screen device. Users chooses “language”, “genre”, “year” and then “prices” consecutively which leads to a result of matching books (or no matches). You may use a ViewStack to display the options at each stage so that only one set of menu is presented to the user at a time. In your ViewModel, you may have the following:

///ActionScript
public static CRITERION_LAN_SET:int = 0;
public static CRITERION_GENRE_SET:int = 1;
public static CRITERION_YEAR_SET:int = 2;
public static CRITERION_PRICES_SET:int = 3;
[Binding] public var selected_criterion:int;

/**Hook to a “Next” button or an item in each of the aforementioned selection menu so that when the user taps on it, the ViewStack can advance to the next menu */
[Binding] public function addToSelectedCriteria():void
{
if(selected_criterion < CRITERION_PRICES_SET) selected_criterion++;
}
///mxml
<mx:ViewStack selectedIndex=”viewModel.selected_criterion”…/>

So if you decide to have a desktop version that can present all the selection criteria at a time as opposed to one by one, you will then no longer need addToSelectedCriteria() or selected_criterion in the ViewModel.

Data binding is an adapter in declarative UI programming which enables developers to program in higher level when dealing with user interaction. Without the plumbings provided by data bindings and commands, etc., you would need to manage UI states directly with “code” that manipulates the View — but you would probably prefer to delegate this kind of lower level manipulation to more specialized objects, as opposed to dealing it directly with your ViewModel — while with Flex and WPF, you delegate these tasks to the framework.

In conclusion, the whole point of all these fancy patterns still nails down to the very basic stuff about programming, things such as breaking down different levels of tasks into different layers and chunks of code, such that your code maintain a hierarchical structure in terms of abstractions (called “decomposition” or “stepwise refinement”). This results code easy to understand, maintain and modify. It’s worth pointing out as we step back for a moment to take a breath and look at a bigger picture.

Binding XML as dataProvider in Flex 4

April 10, 2010

Problem: You want to bind an XMLList object (such as the results you get from a static or dynamically generated XML file) as the data source for some views (called data provider components) in your UI. You assign the XMLList to the dataProvider property like this:

<s:DataGroup dataProvider="{menuLoader.lastResult.step[0].item}"
itemRenderer="components.MMChoicesItemRenderer">...</s:DataGroup>

<s:HTTPService id="menuLoader"
resultFormat="e4x"
url="mymenu.xml"
fault="onMenuHTTPFault(event)"
result="onMenuHTTPResult(event);"/>

But you get a runtime TypeError,  something like:

TypeError: Error #1034: Type Coercion failed: cannot convert XMLList@284a62a9 to mx.collections.IList.

Reason:

Despite the fact that it’s named “List”, XMLList turned out to be a top level Flash object that doesn’t implement the mx.collection.IList interface, which is required for a data source to be qualified as a DataProvider. The commonly used classes that implement IList are ArrayCollection, ArrayList (curiously) and XMLListCollection.

Solution:

The TypeError happens when you tried to set the resultFormat of your HTTPService to “e4x” and bind it directly to the dataProvider property of some components.

Option 1 is to wrap the XMLList into an XMLListCollection before using it as a dataProvider. Like so:

<s:DataGroup dataProvider="{new XMLListCollection(XMLList(menuLoader.lastResult.step[0].item))}" >...</s:DataGroup>

Option 2 is to not use “e4x” as the resultFormat, instead use the default “object” as the resultFormat, then you are free to bind the result directly as dataProvier:

<s:DataGroup dataProvider="{menuLoader.lastResult.steps.step[0].item}" >...</s:DataGroup>

Notice that when the resultFormat is not set to e4x, the HTTPService.lastResult is not the top XML object any longer and you need to drill down one more level to get the XML object.

Also an example from Flex Examples.