Flex Bug with List and toString

I stumbled on this simple and interesting bug with the List component in Flex: Adding an item with a label of “toString” to a List component will break the List, and take down much of your application with it. Just add the following to a new or existing mxml app (tested in Flex 2.0.1):

<mx:List dataProvider=”[‘toString’]”/>

I find this bug interesting because despite thinking it over last night (when I should have been sleeping), I still can’t think of a good reason for why it occurs. The obvious culprit is the correlation between the string value, and List calling toString to get the label, and this somehow causes a conflict. I can’t think of a scenario where this would cause an issue though – calling toString on a string will merely return the string value, regardless of what that value is. I even tested (amongst other things) calling toString on a “toString” String (wow, convoluted) to ensure this wasn’t a deeper player level bug.

I haven’t had time to track down the cause in the framework yet, but I plan to soon. It’s bugging me, because I can’t see why there would be any correlation between this specific value of the label, and the rendering of the list item. I also have a programmer’s natural aversion to edge cases (what if my user adds an item named “toString”, and my whole app blows up?).

Hopefully there will be more, in-depth blog entries to come in the not too distant future. There’s been a lot of interesting stuff going on here at gskinner.com, including our work developing the v3 components set, continued work on our computer vision software, and our expansion into doing Flex work, which I’d love to blog about. Alas, my time is very short at the moment, between work, conferences, traveling, and building a new house (originally designed in Flash, though that’s a story for another entry).

Grant Skinner

The "g" in gskinner. Also the "skinner".

@gskinner

10 Comments

  1. could it be something in the List component using a custom toString method? I use these often in AS2 classes to return a static var that holds my class name. I have noticed AS3 acts differently with a trace(this); inside of a AS3 class by returning the class name.

    static var className:String = “Main”;

    function toString():String

    {

    return className;

    }

  2. I’ve seen the list components blow up too. The list component is interesting because the only items that are in the display list of the list are items that are currently being displayed….so when this starts going awry it can lead to really ugly results. I thought that we’d attributed our mishap to complex item renderers, but after this post, I’m goign to go back and look for toString()…

    Thanks,

    Eric

  3. It is a bug in the ListBase class and the drawItem method. It shows up when you have a data provider with a string value identical to one of the String method names.

    That far I have come the last 10 minutes. I have to go now but I’ll try to narrow it down some more later this weekend.

    Cheers,

    Erwin

  4. *** Found the bug and the solution ***

    Package: mx.controls.listClasses

    Class: ListBase

    Linenr: 3788

    Original code:

    o = selectionIndicators[rowData.uid];

    Fixed code:

    o = selectionIndicators[rowData.uid] as Sprite;

    I have reported this bug to Adobe. Lets hope they will fix it soon. For now you can extend the subclass you are using of ListBase and override the drawItem() method and adjust the code yourself.

    Cheers,

    Erwin

  5. Latest update:

    It will give this error when a method name of the class Object (not String) is being used as string value. Reason for this is because “selectionIndicators” is an Object and when you do selectionIndicators[“toString”] it will retrieve the method within the Object instance that is called “toString”. This means that Object[value] will first seek for a method before it seeks for a variable with that name.

    To be honest I have no idea why it does work when I cast that value to a Sprite. Somehow it appears to leave the methods alone when its being casted.

  6. Latest update:

    I was wrong, sorry guys! Here is my latest findings

    *** Found the bug and the solution ***

    Package: mx.controls.listClasses

    Class: ListBase

    Method: drawItem()

    Linenr: 3768

    Original code:

    if (!selectionIndicators[rowData.uid])

    Fixed code:

    if (!selectionIndicators[rowData.uid] || selectionIndicators[rowData.uid] is Function)

    The original code only checked whether or not the variable already exists in the Object “selectionIndicators”. Because Object always has function like “valueOf” and “toString” it will return a true for these values and starts working with the functions, which of course if not right. To solve this I added ” || selectionIndicators[rowData.uid] is Function” to the IF statement so it will also check whether or not it is a function in the Object. When it is a function it will overwrite the function with the variable given by the data provider and work with that instead of the function.

    This appears to work but it is risky since Object methods will become unavailable when you overwrite them. The real bug in fact that Adobe has made the mistake by using user input values as variable names in the Object. To solve this I probably have to write lots and lots of code in the ListBase class. For now this seems to be the solution since the “selectionIndicators” Object doesnt seem to make use of the Object methods.

    I have reported this bug to Adobe. Lets hope they will fix it soon. For now you can extend the subclass you are using of ListBase and override the drawItem() method and adjust the code yourself.

    Cheers,

    Erwin

  7. Another workaround would be to declare Objects in the dataprovider than strings (i guess thats a better practice). Here are some examples…

    OR

  8. Some problem in pushing code here. I’ll mail it to you, drop me a mail.

  9. Thanks Raghu! I got your email. Check your inbox, there should be a mail there.

Leave a Reply

Your email address will not be published. Required fields are marked *