0

I cannot access values in Flex Object (ArrayCollection) after I receive it from Zend AMF. The original type sent is PHP associative array which is simply returned like

return $this->sections['initial_setup'];

PHP Variable view:

sections array in variable view

The required result sent looks like this in Charles AMF RPC tab:

Charles proxy AMF RPC view

But when I receive the data in Flex as Object (or String[] - it doesn't matter), I cannot access the property values in such code

    var result:Object = event.result;
    if (result['database'] == 'yes' && result['admin'] == 'yes')
        // continue branch ...

and I get exception on the if-line:

    Error: Unknown Property: 'database'.
        at mx.collections::ListCollectionView ...

Finally, I can see in Eclipse variables view that ResultEvent instance carries a result of type ArrayCollection with 0 length and the values received are visible with D icon (I couldn't find what D adornment means):

ResultEvent variable

But why I still can't access them at all and what should I do to use them?

I have tried to change types of Array or ArrayCollection instead of Object. Also there is a thread discussing similar problem, but after trying that out, it doesn't help too.

Any help will be much appreciated :o)

EDIT 1: Here is the code of FB generated super class constructor for the ConfigurationService:

    // Constructor
public function _Super_ConfigurationService()
{
    // initialize service control
    _serviceControl = new mx.rpc.remoting.RemoteObject();

    // initialize RemoteClass alias for all entities returned by functions of this service

    var operations:Object = new Object();
    var operation:mx.rpc.remoting.Operation;

    operation = new mx.rpc.remoting.Operation(null, "readSettings");
     operation.resultType = Object;
    operations["readSettings"] = operation;
    operation = new mx.rpc.remoting.Operation(null, "writeSettings");
    operations["writeSettings"] = operation;
    operation = new mx.rpc.remoting.Operation(null, "readDBSettings");
     operation.resultType = valueObjects.ConnectionParams;
    operations["readDBSettings"] = operation;
    operation = new mx.rpc.remoting.Operation(null, "writeDBSettings");
    operations["writeDBSettings"] = operation;
    operation = new mx.rpc.remoting.Operation(null, "readInitSetupCompletion");
     operation.resultType = Object;
    operations["readInitSetupCompletion"] = operation;
    operation = new mx.rpc.remoting.Operation(null, "writeInitSetupCompletion");
    operations["writeInitSetupCompletion"] = operation;

    _serviceControl.operations = operations;
    _serviceControl.convertResultHandler = com.adobe.serializers.utility.TypeUtility.convertResultHandler;
    _serviceControl.source = "ConfigurationService";
    _serviceControl.endpoint = "gateway.php";


     preInitializeService();
     model_internal::initialize();
}
Community
  • 1
  • 1
Kuba
  • 510
  • 3
  • 13
  • I'm unclear why the ResultEvent.result is an ArrayCollection when it should be an object ( http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/mx/rpc/events/ResultEvent.html#result ). Are you doing something to cast the results of a service call as an ArrayCollection? If so, can you show that code? An Associative Array isn't actually an Array, it's more like a Dictionary or an Object. I would not expect you'd be able to cast an Associative Array to an Array or ArrayCollection. – JeffryHouser Jun 21 '12 at 20:43
  • @www.Flextras.com I don't do anything with results before it comes in ResultEvent, so I don't cast it either. Actually, the service code is generated with FlashBuilder service wizard. I have edited the question and added the constructor service code, where you can see that result type for `readInitSetupCompletion` operation is `Object`. However, when the `convertResultHanler` is called the result type changes from [] to `ArrayCollection`. But I cant find the src code of the `convertResultHanler`. I would be very happy, when it would stay as `Object`, so I could hopefully access its properties. – Kuba Jun 22 '12 at 00:46
  • I'm not aware of the method and it isn't coming in a Google search; but my suspicion is that this method is converting something in a way that it shouldn't be. – JeffryHouser Jun 22 '12 at 01:29
  • Yeah, I couldn't find it too and I have the same suspicion :o) I will try to figure it out somehow later. In the meanwhile it works, when I create some dummy VO with attribute names like are the keys in PHP array. I am just afraid it isn't too flexible in this way. – Kuba Jun 22 '12 at 01:42

1 Answers1

1

So what's happened here is that the Array that's serving as the source for your ArrayCollection is acting as a generic Object with those same two properties. Probably the generated code is assuming you'll always get back more than one object and is having problems when your data doesn't fulfill the assumptions Adobe's engineers made about it. One of the reasons I don't like generated code :-).

Check out these resources on how to "roll your own."

  1. Thoughts on Remoting
  2. AMFPHP to Flex Object Relational Mapping
  3. Implementing PHP Services

I think this last (3) is closest to what you probably have in PHP. If you do decide to go with a VO, you can probably just add an $explicitType to your row return and not need to change too much else on the PHP side. You'll probably need to regenerate your services if you go that route, because I suspect the generated code will be different. The good news is the Adobe engineers probably did think of the case where you have an explicit type, but only one record.

Another fix is to just check your AC for having a source of zero length that is not null and looking for your properties on the edges of that.

Amy Blankenship
  • 6,485
  • 2
  • 22
  • 45
  • Thanks for answer. The first paragraph of yours suggests probably good explanation which made me to realize that ArrayCollection could be just a collection of returned Objects (but the properties don't fit the ArrayCollection rules - they are different, so they're not recognized) unless specified by using an explicit type. That's why I m using the explicit type now. I went with the generated code just because I thought it might be easier to manage data services, but it's proving to be a bit difficult. Next time I'll try it according to your links and see which way is better for what. Thanks :) – Kuba Jul 07 '12 at 13:58
  • Aah, I see quite good suggestion in your last paragraph, but I can't see how would I implement that - specifically looking for the properties from the not null source. Can you give me some hint? – Kuba Jul 07 '12 at 14:09
  • If it's zero length, then the "object" part is being used, which will probably expose its properties with a for each loop. – Amy Blankenship Jul 07 '12 at 18:00
  • Yeah, that's a good hint. But when I'm using for each loop it shows only values of the items. Unfortunatelly because it accesses the properties in random order I can never rely on what value it is. However I can already work with that when I'll get the value order along with property names order using for..in loop. That solves the troubles of using any (even dynamically built) PHP associative array and I don't need to specify explicit type in advance now... Thank you Amy! – Kuba Jul 10 '12 at 02:30
  • You're welcome. You could also use a regular for loop rather than a for each loop, which will tell you both the name of the property and its value. – Amy Blankenship Jul 10 '12 at 17:03
  • Sorry, for being so blind, but I can't see the use of regular for loop properly for this. If I do `var i:int; for (i = 0; i < result.size; i++) { // code here would never run because of size 0 ... }`. Is there some other for loop implementation or condition I should use for this? I'm new to Flex and AS and here's much more of different ways to do one thing in comparison to Java ;o) – Kuba Jul 10 '12 at 22:27
  • try: for (var prop:String in source) {trace(prop, source[prop])} http://livedocs.adobe.com/flex/3/html/help.html?content=03_Language_and_Syntax_16.html – Amy Blankenship Jul 11 '12 at 00:50
  • Aaah, now I see Amy... All the time, I was accessing the AC result as `result['database']` and that was giving the error. Now, I see it has to be accessed as `result.source['database']`. That's so simple that I feel ashamed it took me so long to get it :o) (blushed) As my mum says: Why to make it easy if you can make it difficult? Yep, that's me lol – Kuba Jul 11 '12 at 23:57