Archive for the ‘ActionScript 3’ 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.

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>
...

* vs. Object in ActionScript 3

March 22, 2011

ActionScript 3 doesn’t support Generics like some other languages such as Java. In the case you need to return a Generic type, e.g., your client code is expecting certain type, but the code that provides the service doesn’t know what type it is going to be, you simply use star (*), as opposed to Object:


public function createWindowInstance(type:Class,
allowMultipleInstances:Boolean = false):*
{
...
var windowToOpen:*;
windowToOpen = new ClassFactory(type).newInstance();
spark.components.Window(windowToOpen).open();
return windowToOpen;
}

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

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.

Autohide UIScrollbar on a dynamic text field – AS3

February 22, 2010

mUIScrollBar.visible = (mTextField.maxScrollV > 1);

“Error #1088: The markup in the document following the root element must be well-formed.”

December 5, 2009

I was using PHP and curl as proxy to get some xml files from Basecamp for my Flex UI to consume and was successful (something like “return $response   = curl_exec($session);“. But after I refactored my little php functions into an object/class and included it in another delegation file, it suddenly stopped working. In Flex, I got the following error for the HTTPService fault event:

faultCode:Client.CouldNotDecode
faultString:’Error #1088: The markup in the document following the root element must be well-formed.’
faultDetail:’null’

In Firefox 3.5, the output XML file looked ok. But both Safari and IE gave error messages: There was an “*” in front of the <?xml ..?> header in Safari source code view; while IE gave the following error:

Invalid at the top level of the document. Error processing resource

After comparing the files before refactoring and the one after, I noticed that the refactored one was encoded in UTF-8 while the old one was in ANSI. After I converted my class file into ANSI, XML output became normal in all three browsers.

BTW, I used Notepad++. Not sure if that was an issue.

Anyhow, lessons learned: Make sure the source files are encoded in ANSI.

Any comments and thoughts are welcome!