ArrayCollection, Arrays and Server Data

I call this the “array of one” problem. I make a request to the server for some data, usually a list of things, and it comes back and I stuff it in a dataprovider and it displays just fine….sometimes. Sometimes I get an error about converting/coercing ObjectProxy into an Array or ArrayCollection. After further investigation it turns out that it is only if the list of things has zero or one items that I get the error.
This is an unfortunate fact-of-life when serializing objects as xml. XML is really just formatted text, so all type information is essentially lost. We don’t know if the data is a String, Number, Array or Object and end up making a good guess.
For example, if I have the following data to send:
class Employee
{
var Name:String = “Alex”;
var EmployeeID:Number = 123;
}
It gets serialized as a one string
“Alex123”
On the receiving side, the code sees that there isn’t anything numeric about “Alex” so it leaves it as a string, and that “123” is all digits so it parses it as a Number.
Now if the data is a list of values such as
class Manager
{
var Manager:String = “Steve”;
var DirectReportEmployeeIDs:Array = [123, 456, 789];
}
That might get serialized as:
Steve123456789
On the receiving side, the code sees that there are multiple so it decides to make an Array of those values.
Now if there is only one direct report, the data is going to come over as:
Steve123
and sure enough, it no longer looks like an array, does it? That’s why this is the “array of one” problem.
So, how to deal with it? There is no single right answer. There are type-preserving serialization technologies but they aren’t as popular. You can just check to see if the thing you think is an Array or ArrayCollection is, and if not, convert it to an array by pushing onto a new array, or you can work with the data as XML and use XMLListCollection which will see the “array of one” as an XMLList.
To check, you would add code like:
if (event.result is ObjectProxy)
list.dataProvider = [ event.result ]; // short cut for new array()
else
list.dataProvider = event.result.
To use XML and XMLListCollection, set the resultFormat=”e4x”.

4 Responses to ArrayCollection, Arrays and Server Data

  1. daMage says:

    If you are putting sample xml code on this page use < instead of . Otherwise id won’t be displayed properly.
    —————-
    OK, thanks.

  2. Bob says:

    I have a possibly unrelated question, but I don’t know where else to turn at this point:
    I am populating some ComboBoxes with an ArrayCollection from some XML data and using the ComboBoxes to filter a DataGrid. In the case of the first ComboBox, which is pulling from the “timeframe” labelField, it has many values but they are all either “Weekly” or “Monthly.” I want to de-dupe the ComboBox so it displays only “Weekly” and “Monthly” once each. I have tried the de-duping code at:
    http://nwebb.co.uk/blog/?p=18
    But that code does not seem to work on an ArrayCollection that is passed in from an HTTPService. I have tried getting the childNode, firstResult etc. from XMLNode but nothing seems to work. Can you point me in the right direction?
    ————–
    Don’t have time to look at your code right now, but I would try stuffing each string into an object, then using for..in to read out the strings.
    Did you ask on FlexCoders?

  3. Kevin says:

    The ‘array of one’ problem only seems to apply to HTTPServices, not WebServices.
    It would be nice if you could easily cast an ‘array of one’ to an ArrayCollection. Obviously you can painstakingly build a new ArrayCollection by hand, but it would be nice if you could just add ‘as ArrayCollection’ after the the variable and it would automatically become element [0] in the new ArrayCollection.
    ———————
    Alex responds:
    I thought ArrayUtil could do that…