13 Replies Latest reply on Mar 28, 2008 12:07 PM by recordbuyer

    httpservice object data / class variable issue

    recordbuyer
      Hi,

      I'm building a Flex app with ActionScript classes where the classes contain all of the event handling. In an class such as:

      package stuff {
      public var xml:XML() = new XML();
      public function MyObject() {}
      public function getData():void {
      // in here I create an HTTPService object, fill out all the info and send it.
      }
      public function resultHandler(event:ResultEvent):void {
      xml = XML(event.result);
      // I get the xml just fine here, but after this call ends, I can't get this data anymore
      }
      // fault handler, etc.
      }


      The problem is that if I want to see/use that data within the result handler, it's fine, but if I try to store this data into a class variable, I cannot retrieve this data from outside the class. If I refer to this object from another object, get the data, everything's fine, and I can see the xml from the result handler, but I can't seem to store this data and retrieve it via a class variable, nor via a getter method that returns this variable. Is there something that I'm missing here? Basically I want to retrieve the info via the HTTPService, and store this info into a class variable that I can later access. How can I do this?

      Thanks.
        • 1. httpservice object data / class variable issue
          levancho Level 3
          your example code seems liitle wrong, I dont see class declaration, but assuming you have class declaration you can do following inside your class :


          private var _myxml:XML;
          public function get myxml () : XML {
          return this._myxml;
          }

          in your result do this :


          public function resultHandler(event:ResultEvent):void {
          this._myxml = XML(event.result);

          }

          then you can just get refference to that xml following way : yourClassInstance.myxml


          (you can also do a bindable way as well) .

          • 2. Re: httpservice object data / class variable issue
            ntsiii Level 3
            If you plan to bind to this data, use the [Bindable] metadata tag.
            Tracy
            • 3. Re: httpservice object data / class variable issue
              recordbuyer Level 1
              Hi, thanks for your responses. Yes there's a class declaration and I'm pretty much doing what you've suggested. This works just fine as a normal case of object-oriented structure, it only seems to fail when using an encapsulated resultevent handler, and I'm not sure why. In most other OO languages I've used, this example is trivial. That's why I'm wondering if there's anything specific about ActionScript/Flex that is making this more complicated that I'd normally imagine.

              Bindings are not the issue, it has to do with saving data from a result handler (which is part of a class) into a class variable and being able to retrieve it.

              In fact, within the same class,

              private var _result:XML;

              public function getResult():XML {
              // THIS ALERT WILL NOT SHOW THE XML STRING
              Alert.show(this._result.toXMLString());
              return this._result;
              }

              public function httpResult(event:ResultEvent):void {
              this._result = XML(event.result);
              // BUT THIS ALERT WILL SHOW THE PROPER XML STRING!
              Alert.show(this._result.toXMLString());
              }

              I'm perplexed. Anyone else have any ideas? Thanks.
              • 4. httpservice object data / class variable issue
                recordbuyer Level 1
                After a lot of experimentation, it appears that ActionScript's OO implementation does not allow storing the results of a ResultEvent handler as a class variable. This seems to go against most other OO language's normal behavior. I can't seem to figure out what's going on. The best answer I can find in any Adobe documentation is to "do" something with the result, and unfortunately, "doing" something seems to exclude "storing that result as a class variable". My only solution or workaround for this bug is to do just that... "do something with the variable". This means taking the result and putting it somewhere else. If anyone understands this problem or how to store the result within the class, please let me know, as I'd love to work with ActionScript in a more standard OO context than having to do this workaround, which just adds extra theoretically unnecessary code. Thanks.
                • 5. Re: httpservice object data / class variable issue
                  ntsiii Level 3
                  No, you can certainly do this, I am doing it right now, very similar to what you are doing, including using XML. My result handler handle s all of the calls in the app, and based on a property in the AsyncToken, assigns it to the appropriate instance variable. The bindings fire and my UI is updated as I expect. In fact this is a very common and advised practice.

                  You have something else going on. Try using xml.copy() to your variable. ( I am not, except when I want to save an original copy of my data for undo functionality) But I am just trying to figure out what is wrong in your implementation.

                  I do not see anything wrong with your code. Mine looks almost identical.

                  Also, still grasping at straws, try implemeting your data property using a getter function.

                  But don't give up. You just need to find your problem.
                  Tracy
                  • 6. Re: httpservice object data / class variable issue
                    levancho Level 3
                    make sure you have resultFormat="e4x" off service otherwise resultEvent.result is not anough.
                    • 7. Re: httpservice object data / class variable issue
                      recordbuyer Level 1
                      Hi Tracy, thanks for your response. I do want to mention that this "bug" seems only to occur if the class is completely external to the main application mxml flex code. If I do all of my event handling (and bindings) within <mx:Script> tags within the main application mxml, everything works fine. The problem is that I'm not doing this since I'm trying to separate out the functionality into appropriate classes (and each class with its own event handling functions). So the class that is suffering here is imported in the main application file, then objects created and used.

                      In your working setup, are you doing the event handling in a completely separate ActionScript class file? or are you including your actionscript within the <mx:Script> tags of yr flex app? This is why I'm wondering if this is an ActionScript OO issue, or if there's some strange particular aspect of ActionScript coding that I'm not aware of. If your actionscript classes are indeed external to the main mxml file, would you be willing to post the generic code chunks of your working version?

                      Do you see anything odd here:
                      1. Create object
                      2. Call httpservice via the object which sends result to internal eventHandler
                      a. This eventHandler receives the XML
                      b. Store this XML in a class variable (<-- the XML certainly arrives as XML, but this assignment doesn't seem to work)
                      3. Access the object's variable (<-- gets a null value since nothing is getting stored)

                      Neither public properties, nor getter methods seem to get anything other than null.
                      • 8. Re: httpservice object data / class variable issue
                        ntsiii Level 3
                        I am accessing my data in two main ways, one is binding and one is using a ChangeWatcher.watch to call a function. I do also make a few direct calls.

                        I do not see anything wrong with your process.

                        Ah, I see one significant difference. I am using the singleton pattern. Each sub-component does getInstance() to get a reference to the data class. Then I bind or use a changewatcher against that reference.

                        Is is possible that you are looking at two different instances of your data class? That would explain this problem.

                        Maybe set a timestamp var using Date.time in the constructor, and trace it in a getter function to be sure.
                        Tracy
                        • 9. Re: httpservice object data / class variable issue
                          recordbuyer Level 1
                          Hi Tracy, how could I know if there are two different instances of the class? I only create and try to access it once! Basically I do:

                          var myClass:MyClass = new MyClass();
                          myClass.loadData(); // this is the function that sends the HTTPService request
                          myClass.getData(); // This gives me null

                          In the class, if I put an Alert in the actual ResultEvent handler, I get the XML (using _xml.toXMLString()),
                          but when I try to access the data via myClass.getData(), the _xml variable is null.
                          It seems to me that the assignment of the XML to _xml isn't taking place.

                          Is it possible that random other objects are being created? I don't know why this only seems to affect this eventHandling activity. Assigning and retrieving class variables works fine.

                          Any other ideas? Thanks
                          • 10. Re: httpservice object data / class variable issue
                            levancho Level 3
                            IMHO< your problem is trying to accesses asynchronous data synchronously,

                            you can't do this :
                            ---------------------------
                            myClass.loadData();
                            myClass.getData();
                            ------------------

                            myClass.getData();<-- this will almost always give you null result,
                            (at least at initial call, until last result variable is not set) .
                            you have to get data after result is returned, via resultEvent listener.
                            • 11. Re: httpservice object data / class variable issue
                              recordbuyer Level 1
                              Hi levancho, could you propose a solution? How can I get the result from the ResultEvent to get stored as a class variable, and then access this variable later? The loadData() call sets off the HTTPService and that should in turn get the data through the ResultEvent handler, and I know this data gets there, but how do I set this result as a class variable, and how can I access it later, via a function call? Or should I be designing this differently? Thanks.
                              • 12. Re: httpservice object data / class variable issue
                                Bayani Portier Level 1
                                If I may step into the ring here.

                                If you are asynchronously getting data from a server, you can't in the next line of code access the data. What you need to do is to either wait for an event, or push the data in the result section onto a binding, thus implicitly using an event.

                                Picture a game of tennis. If you hit the ball to your opponent, this is like making a server request. If you try to hit the ball again, it is not on your side of the court. Hence, the variable is null. You have to wait until the ball has been hit back by the server, and then you can do something with it again.

                                An alternative to what you are trying to do if you are not following the cairngorm pattern, is to pass a callback function within the event.

                                EG:
                                public function doStuffWithGetData(insertVariables):void
                                {
                                //do stuff
                                }

                                (in myClass)
                                public function loadData(callBack:Function=null)//in case you don't want a callback function

                                myClass.loadData(doStuffWithGetData):void
                                {
                                //call server, passing doStuffWithGetData into event
                                }

                                public function onResponse(e:CairngormEvent):void
                                {
                                //response code
                                e.callBack.call();
                                }

                                Hope this helps.

                                -b
                                • 13. httpservice object data / class variable issue
                                  recordbuyer Level 1
                                  Thanks for all of your suggestions. The final problem was indeed the asynchronous nature of the HTTPService data calls. I found a series of articles that highlighted and provided solutions to the issue. An important quote from one of the articles is: "The fact that flex web service calls are asynchronous have implications on how you design your code." and even, "the asynchronicity of remote calls has a major impact, on how you design the client."

                                  This is exactly the sort of information I was missing, and didn't find well described in any of the Adobe Flex 3 documentation or tutorials that I read.

                                  Here are some links to the most useful articles I found:
                                  http://tinyurl.com/34py5p
                                  http://techpolesen.blogspot.com/2007/09/coping-with-flex-asynchronous-remote.html
                                  http://techpolesen.blogspot.com/2007/09/coping-with-flex-asynchronous-remote_26.html
                                  http://techpolesen.blogspot.com/2007/11/coping-with-flex-asynchronous-remote.html