IN operator differences in FlashPlayer 10.1 causes Advanced Data Grid multiple selection bug

One of the more subtle changes in FlashPlayer 10 vs FlashPlayer 10.1 is that the behavior of the IN operator has changed. The IN operator when used to loop over the properties of an object will return it's keys in a different order each time you run a program.

If you run this code several time you see the order is different each time:

view plain print about
1var person:Object = {};
3person.firstName = 'Justin';
4person.lastName = 'Mclean';
6for each varr property:String in person) {
7    trace(property);

Sometimes you get Mclean then Justin other times you get Justin then Mclean. No big deal your code still does the same thing right?

Well consider this code:

view plain print about
1var map:Object = {}; = 'one';
3map.two = 'two';
4map.three = 'three';
6for varr item:String in map) {
7    delete map[item];

Sometime this will work and occasionally the map will end up an items in it depending on the order the items are deleted. Not exactly what you may of expected.

But of course no one would write code like that would they? Delete items from an object (or array) while looping over it is generally not done.

Well sadly code like this does exist and it's in the Flex SDK and the AdvancedDataGrid.

It only shows itself if you are using multiple cell selection and then it displays the wrong selection as you scroll - rather annoying really.

The offending functions are:

  • removeIndicators
  • clearCellIndicators
  • adjustAfterRemove
  • onTweenEnd

Fixing removeIndicators and clearCellIndicators will sort the issue (adjustAfterRemove doesn't seem to be called at all). Here's how removeIndicators method can be fixed. ie save the keys in an array then looping over that array and delete them from the original object.

view plain print about
1override protected function removeIndicators(uid:String):void
3    if (isCellSelectionMode())
4    {
5        var keys:Array = [];
6        for varr p:String in cellSelectionIndicators[uid]) {
7            keys.push(p);
8        }
10        for each (p in keys) {
11            removeCellIndicators(uid, int(p));
12        }
14        delete visibleCellRenderers[uid];
15    }
17    super.removeIndicators(uid);

The clearCellIndicators method can be fixed in a similar way.

There may be other parts of the Flex SDK (or 3rd party code) that have this issue, hopefully you'll not run into it.

Comments (Comment Moderation is enabled. Your comment will not appear until approved.)