More on ExternalInterface

english mobile

One of my first posts was about using ExternalInterface to call Flex from Authorware, and about how there is virtually no documentation on how to use this API to run functions inside a Flex swf from an ActiveX control embedded in an executable (in this case, Authorware). I've found some more anomalies which are worth jotting down for my own future reference and the reference of anyone who's bored enough to read my blog.

It seems that the <arguments> parameter does not recognize the full spectrum of data types supported by Flex. So far, I have found that if your Flex function expects an int or a Boolean argument, these values must be wrapped in a <number> tag. I guess Flex knows ExternalInterface can't handle these data types, and converts them from generic numbers into the appropriate data type by pfm in the background.

Ain't life grand?

Showing item number in ItemRenderer

english mobile

I asked a question several weeks ago on the FlexCoders forum on how to get the item number of an item that had been clicked in a Repeater. None of the answers that I got seemed to help and it wasn't that critical, so I let it drop. In my current project, it is critical, because I have to show that number on the screen.

Luckily, I am using XML. E4X XML, like Authorware icons, is very "self-aware." In Authorware, you can get from any place in the program to any other place using the numeric values implicit in the parent/child relationship. Similarly, an E4X XML node "knows" what its child number is relative to the parent node. So displaying the node number on the screen was as simple as {data.childIndex + 1}.

Some days Flex is really cool :-).

Updated 12-3-08:
I've posted a simple example that shows how to display the line number in a List based control with either an XML or ListCollectionView source.

Order of Events for ItemRenderers

english mobile

I suspect that I'll be blogging a lot about ItemRenderers, because it seems that there's a ton that can go wrong with them and lots of stuff to learn before you can get it right. A good starting point in learning about them is Alex Harui's Blog. I found this source a bit misleading in my current project, because it suggests that you should run your init code in the dataChange event listener function.

The problem I found is that the dataChange event runs before some objects in the component have been instantiated, so trying to change their attributes results in a spectacular explosion. The solution I found is to set a boolean value in the creationComplete listener to indicate whether or not the component was completely drawn, then run the same logic that would have run from the dataChange function. So when the data changes, the dataChange listener will initialize the objects, but on first creation, the creationComplete listener handles it.

I suspect this is not the optimal way to handle this, but it works and doesn't require much rocket science on my part.

Update 7/3/2008: I eventually had a series of conversations about this with Alex, and it seems that the mistake I was making was that I was trying to address objects directly in the dataChange event handler, and, as noted above that doesn't work. But instead of repeating that call in dataChange and creationComplete, what I should have done is to set a boolean flag in dataChange only to indicate that the property (which in this case was a dataProvider) needs to be set on the child object.

I was trying to avoid overriding any of the inbuilt methods, but the engineers intended for developers to override many of the methods when creating itemRenderers. In this case, I needed to override commitProperties and set the dataProvider whenever that flag was true (and then set the flag back to false, of course).

Unhandled Error

english mobile

I am often trying to do sort of off-the-wall things in Flex, because I am slowly building new functionality in Flex that gets plugged into Authorware. When enough of the functionality exists in Flex, we'll rebuild the shell logic to finally port it all to Flex. But for right now I find myself doing things I suspect the Flex team never intended.

For instance, last week I was sending XML in through ExternalInterface that contained XML that was destined to be the htmlText for a TextArea (I have more fun and interesting posts about that to come later). But the upshot is that I was getting "Error #2044: Unhandled IOErrorEvent:. text=Error #2036: Load NeverCompleted." I thought it was a problem with the XML getting through the ExternalInterface or maybe with the parsing or possibly with the component that was displaying the content. I couldn't find anything on this error, so I was pretty much stumped.

As it turns out, the problem was that I'd gotten the path to an image in the HTML slightly wrong, and when that didn't load, I got the error. A secondary issue was that the latest Flex Beta spits out a debug swf by default, so this helpfully shows the error to anyone and everyone unless you go out of your way to put out a production version. I'd forgotten about this new quirk, so this was fairly alarming in a file I'd planned to pass along to my client.

Anyway, we're going for dinner now. Ta.