Check out our Angular Book Series.

Why does ColdFusion return a CFC to Flex as a generic object?

Adobe has gone through a lot of trouble to make sure that ColdFusion and Flex play really nice together. When you pass an ActionScript object to a CFC method, CF (Using an embedded version LiveCycle Data Services ) will automatically turn that ActionScript Object into a CFC instance. When ColdFusion passes passing a CFC back to Flex, that CFC will turn into a ActionScript object.

Conceptually this is great. Unfortunately, the reality is that you must be very particular in your implementation or this will not work. If you don't set it up properly, Flex will view the result CFC as a generic Flex object, not your custom AS3 object. It took me a few days of banging on this before I got it; and I never had a problem again. I thought I would try to impart some of my wisdom.

First, you want to make sure that your AS3 object maps to the CFC on the remote server.


[RemoteClass(alias="com.DotComIt.project.ClassName")]

The CFC will have to be located in the alias path in the web root. On my dev machine this is something like "C:\wwwroot\com\DotComIt\project\ClassName.cfc". Be sure that the alias is case sensitive to the directory path. Even if you're on a windows unit, case sensitivity matters.

Second, make sure that all the instance variable of the object matches is defined as a property on the AS3 object. Based on my dealing with this you can define simple properties (AKA public variables ) or complex properties (with get and set methods) and it still works. In this case I've only used get set properties sparingly. On the CF side, you want to be sure to define every property in your AS3 object using the cfproperty tag. You must be certain to retain the order of property names and the case sensitivity of each one. If not, the objects won't translate.

Even with these two items checked off, there is another item to be aware of. Often when dealing with Cairngorm I'm turning a ColdFusion query into an array of Value Objects. Each value object is mapped from a CFC to an AS3 object using the above approach. However, if an instance of the custom AS3 object is never created inside the app, then your custom objects will be returned as generic objects. So, when I'm always returning an object as an array (as oppose to an individual object), I'll often add a line of code like this:


var myObject: MyCustomClass;

somewhere in the application. In Cairngorm I'll put it in the model locator; otherwise I might create it in a CreationComplete event.

I believe the reason for this is that the Flex Compiler is doing too much optimization. Even though the custom class is in my Flex project, if the compiler doesn't seen an instance of the class it removes it from the final swf. And as such, the final swf doesn't have the class definition and doesn't know what to do with it.

WebORB offers this type of functionality for technologies other than ColdFusion. I've done some work with WebORB for .NET. It might be worth noting that for the object to transfer properly from Flex to a .NET Assembly, you must add a mapping to the weborb.config file. Your custom mapping will look something like this:


<classMapping>
<clientClass>com.DotComIt.project.ClassName</clientClass>
<serverClass>com.DotComIt.project.ClassName</serverClass>
</classMapping>

The 'clientClass' is the package of the ActionScript object and the serverClass is the location of the object in your .NET assembly. The path names do not have to be identical with either technology, but I find it easy to keep things straight if they are.

Related Blog Entries

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)
Tom Chiverton's Gravatar The ColdFusion extentsions for Eclipse/Flex Builder allow you to right click a CFC (with cfproperty tags, like reactor.project.foo.To.barTo) and generate an AS class with the right case, public properties etc. etc.
# Posted By Tom Chiverton | 10/9/07 9:58 AM
mike nimer's Gravatar Don't forget the CFCOMPONENT alias="" attribute. It should match the [remoteClass(alias="")] value exactly.

It's technically optional, however when using CFCs as Value objects you should consider it required. It will help a lot with the back and forth.

---nimer
# Posted By mike nimer | 10/9/07 10:19 AM
Jeffry Houser's Gravatar Tom,

I'll have to check them out. Does it work both ways? I often find myself creating the AS3 components first.

Mike,

Wow, I never even heard of that. Thanks for the tip.
# Posted By Jeffry Houser | 10/9/07 11:05 AM
Tom Chiverton's Gravatar Jeffry,
Sure, you can right click a AS class and do 'create CFC'. We normally go the other way around to you obviously :-)
# Posted By Tom Chiverton | 10/9/07 11:08 AM
Ged McB's Gravatar Two tips:
1) When using the wizzard to make the CFC valueobject remove the [RemoteClass(alias="cairngorm_cfc_3.cfcs.LesVO")] line or the VO will not write in full.
2) Make sure you compile your AS VO before requesting it from CF. Sounds ovious but cost me 5 hours !
# Posted By Ged McB | 10/26/07 5:45 AM
Rachel's Gravatar This is really helpful - thank you Jeffry.

One question I have - I am encountering the issue you mention where CF is returning an array of generic objects to Flex instead of an array of typed objects. I know the aliases are correct, because elsewhere the data displays ok and when I change it, I get errors.

I tried creating an instance of one of the typed objects with the initialization of the component I'm working with, but I'm still getting generic objects.

The only way I've gotten it to work with typed objects is to actually loop through the array returned from CF, and manually create typed AS objects from the generic ones.

So am I misunderstanding how you're using the instance of the object, or am I doing it correctly and the manual creation of each object is required?

Thanks
# Posted By Rachel | 3/18/08 12:07 PM
Jeffry Houser's Gravatar Rachel,

If you could share some code, it that may help diagnose the issue.

If ColdFusion is creating an array of value objects (AKA CFCs) that are properly aliased to AS3 objects, then the conversion should be automatic if you are using RemoteObject to retrieve the data.

If you are just returning a query, then you see correct behavior. The Flash Player sees query rows as generic objects, not your specially mapped object.
# Posted By Jeffry Houser | 3/18/08 12:42 PM
Rachel's Gravatar Thanks so much for offering to look at it. I've posted the relevant code here:

http://pastebin.com/m3cf70c0e

One thing I am not doing is putting both the AS and CF objects in the same folder/package. I've seen a couple mentions that the alias "must be the same" for both, but if I make them then AS can't find the CF objects. I guess my question is, is it a best practice to keep them together? Is this the source of my problem?

Thanks again!
# Posted By Rachel | 3/18/08 2:02 PM
Jeffry Houser's Gravatar Hi Rachel,

That's 300 lines of code, and it's a bit hard to follow. The code that calls methods on the RemoteObject is not in the sample, so I can't tell which CFC method you're calling. The "getReportsByRole" method that you created a results handler for is not in the CFC.

As such, I can't offer much help dissecting code.

The AS3 Objects do not have to have the same folder / package name as the CF objects.

Make sure your alias paths are case sensitive though.
# Posted By Jeffry Houser | 3/18/08 2:17 PM
Tom's Gravatar Good post, I had a big problem with mapping: I get from a CFC an array of Object(a) containing an array of other object(b). The object (a) was well mapped but no the object (b) because the deep I think.

So I resolve this problem just adding 'private objectb:b;' in my class which do the remote request and magic!
# Posted By Tom | 6/20/08 8:57 AM
Ali's Gravatar Jeff,

I know this blog post is several years old, but I am running into problems between
Flex and CF.
In CF I am generating an Array of Typed Objects. These objects have the same definitions
in the Flex App, so the .as files match my .cfc definitions. However, not only is
Flex getting these as generic objects, it doesn't even show the items in teh array.

The object I am passing back does not have any properties explicitly defined in it. It
extends from a base class that has all the properties defined. However in my loop I am setting
all the properties.

Do you think because the object itself does not have any <cfproperty>'s in it, Flex does not know
what to do with it?

Do you have any suggestions?

Thanks,
Ali
# Posted By Ali | 2/12/10 9:21 PM
Ali's Gravatar Jeff,

Sorry if this is a doublepost, but it seems like
last time I tried posting, my message got deleted.

If this is a duplicate, then please accept my apologies.

I'm generating an Array of CF Objects, where the CF Objects sometimes inherit from a base class. So there are times when a child object will have no properties explicitly defined in it.

I am passing this array of objects back to Flex, but flex is choking. When there is no inheritance involved it can recognize the ArrayOfCFC. However when inheritance is involved, then it chokes.

Do you have any insight into this issue?

Any advice ideas on objects which inherit from other components, which have no properties explicitly defined in them?

Thanks,
Ali
# Posted By Ali | 2/12/10 9:31 PM
Jeffry Houser's Gravatar Ali,

Comments are moderated. ;) My old stuff is getting lots of traffic lately.

Use a tool, such as Charles or ServiceCapture, of the Flex Builder 4 network monitor to see what is being passed back and forth. That may help you diagnose the issue.

I would expect that the Value Object you are passing back needs all the cfproperty tags defined in the object; not in the object parent's, but I haven't tested that.
# Posted By Jeffry Houser | 2/12/10 9:40 PM
Phillip Molaro's Gravatar THANK YOU so much for that bit about defining a custom object type in Flex so my CF Array of custom object types would be correctly recognized in Flex. That has saved the day!!
# Posted By Phillip Molaro | 3/11/10 1:13 PM
Ionectu's Gravatar "Adobe has gone through a lot of trouble to make sure that ColdFusion and Flex play really nice together"

Translation : `Adobe` is retarded and here`s why, it`s quite simple.


With compilable languages, It`s a must to at least pretend to be able to create it once and leave it alone. It`s OOP not HTML ... amf remoting is `dependency central`. NORMAL people need to be able to change one end and not scrue up the entire thing, this is what development is about (in part), continuity, to have a flow that can be easily redirected.

Amf remoting remindes me of something along the lines of

if(this.file == "index")
   displayPage(1);
else if(this.file == "page2")
   displayPage(2);
else if(this.file == "page3")
   displayPage(3);
else if(this.file == "page4")
   displayPage(4);
else
   buy a hamster and teach it oop, it`s gonna come up with something better than Adobe did


The hell ?! Are all Adobe employees Google or Microsoft "rejects" ? (that`s not a nice thing to say, I know and I`m sorry, I`m just really pissed off, it just rubs me wrong.)

P.S. Good article
# Posted By Ionectu | 6/15/10 8:03 PM
Jeffry Houser's Gravatar Ionectu,

I'm not sure I completely understand how you make the leap from "Adobe made sure that CF and Flex play nice together" to "Adobe is retarded".

When you're creating value objects designed for sharing data between two different systems (in this case, CF and Flex), it makes sense that there should be some similarity between them in order to take advantage of the automatic conversion to one object type (CFC) to the other (AS Class).

I believe that all AMF Gateways have similar limitations; no matter what system you're building on.

You're more than welcome not to use that automatic conversion, but then you're stuck writing your own conversion / parsing code as appropriate. Sometimes this is no big deal, sometimes it is a pain. It depends what you're trying to do.

BTW, interesting tidbit if you weren't aware. Most ColdFusion MVC Frameworks I've worked with operate using an algorithm you describe.
# Posted By Jeffry Houser | 6/16/10 12:02 PM
Ionectu's Gravatar In, Adobe`s making sure that CF and Flex play nice together they kind of forgot to teach them, how to understand and help each other.
At the moment all that they can do is copy values from point a to point b (if you have points defined) (If you don`t you`re better off using wsdl btw).
They don`t play nice togheter.. they just copy values from point a to point 1 from point b to point 2, the concept is the simplest I`ve ever seen .... this value goes here, this one here, and .... hm.. yep yep this goes here. Yeah that it. Client.as ....

And if that took them year(s).. well then that`s just sad. They could have spend some time "implementing" some "usability"

How can they as a company think that it`s a success ...
"Ok we did it!" .. "To use it you just have to set the same name, set the same position, set an id, on both ends ... and that might do it, I think that`s all". "We`ll call this a ... bridge? no , no, that`s not FLASHy enough.. we`ll call it a protocol.. yeah protocol" ... How can they call that a protocol :wallbash: when clearly it can`t even stand on it`s own "two" feet.
# Posted By Ionectu | 6/16/10 12:27 PM
All Content Copyright 2005, 2006, 2007, 2008, 2009 Jeffry Houser. May not be reused without permission
BlogCFC was created by Raymond Camden. This blog is running version 5.9.2.002.