In Flex, you’ve performed all of the steps to issue a remote query, and your responder has received the resultevent, and you go to evaluate the payload, and it gives you a null error: “Error #1009: Cannot access a property or method of a null object reference”.
A solution (as described in Peter Ent’s blog):
Assign the result through ArrayUtil.toArray
gallery.photos = mx.utils.ArrayUtil.toArray(data.photo);
(link (solution near bottom) : http://weblogs.macromedia.com/pent/archives/2005/12/day_6_finished.cfm
What’s really going on?
The underlying object carried by the result event is a Proxy Object, and not an ArrayCollection, nor an array. It could look like an ArrayCollection, but only if handled in a particular way.
Why can’t the problem be fixed?
Because the paradigms have been mixed, and they can’t be unmixed.
The paradigms I refer to are what contrast delayed instantiation, which is characteristic of functional programming languages like Scheme, Lisp, and Haskell, and eager evaluation, which is typical of declarative programming languages like C, Java, and PHP. In order to force declarative languages to use delayed instantiation (or lazy acquisition, or lazy loading), a bit of code has to be put in place to manage the laziness properly, and as unobtrusively as possible. The pattern typically used is the Virtual Proxy Pattern.
In this pattern, the interface to the object that is presented, is in fact, a proxy. It may return the real fully populated object, and it may return a shell. That all depends on how it is implemented. In Flex, if an object is not quite ready, you can bind it with no problem, but you don’t want to directly access the underlying object, or its members. There are interfaces (like ArrayUtil) which you can operate through to either force it to load up all of the data, or to tickle the object, and set a listener for when it is populated (basically binding).
The Rich Client interface in Flex, provides many cases where this behavior is desireable, and to force it to load up all of the data is not always appropriate. It is similar to the problem developers run into when they first start trying to actively drive a command into a view that has not been instantiated. They will get a null error. Then, after trying many things, and poring through the books, they find creationPolicy=”ALL”. And the immediate error goes away. That is how you defeat delayed instantiation in your views.
But, the delayed instantiation is there for a reason. It was put in place to solve a problem, and by incrementally removing the solution, without understanding what it solved, is tantamount to inviting or encouraging the problem to surface.
It’s all about timing. And making good use of time, which can be devoured very quickly by rich user interfaces. For anyone who has done Windows programming, or other UI programming, you might be familiar with onDraw() event handlers for views, and how that all happens on a larger reDraw cycle. The same principle applies here. The data and the view are on different schedules.
When I continue, I will look at some code examples, with Haskell first, and then Java, for comparison. Speaking of Haskell, looks like they have an actionscript byte code assembler for Haskell, with support for the Flash 9 virtual machine (AVM2). Great work guys!
(to be continued)