9 Replies Latest reply on May 25, 2008 2:05 PM by puponpup

    How to have constructor wait for xml to load

    puponpup
      How do I have a constructor wait until xml loads before finishing (so that if the class is instantiated the next line of code is useable with the xml). If I put a while loop in, that just stops the xml from loading and hangs the whole program.


        • 1. Re: How to have constructor wait for xml to load
          Level 7
          puponpup,

          > How do I have a constructor wait until xml loads before finishing

          You could write a series of provate init functions, then call them in
          turn. Something along these lines (and I imagine your XML property should
          be private):

          import mx.utils.Delegate;

          class MyClass{
          private var xmlDoc:XML;

          public function MyClass(xmlToLoad:String) {
          init(xmlToLoad);
          }
          private init(xmlToLoad:String):Void {
          xmlDoc = new XML();
          xmlDoc.ignoreWhite = true;
          xmlDoc.onLoad = Delegate.create(this, xmlHandler);
          xmlDoc.load(xmlToLoad);
          }
          private function xmlHandler(success:Boolean):Void {
          if (success) {
          init2();
          } else {
          // error handling code here
          }
          }
          private function init2():Void {
          // rest of init code here
          }
          }


          David Stiller
          Adobe Community Expert
          Dev blog, http://www.quip.net/blog/
          "Luck is the residue of good design."


          • 2. Re: How to have constructor wait for xml to load
            puponpup Level 1
            Sweet! That looks nice. One question, if I'm using Flash CS3 (though set to AS2) should I still do "import mx.utils.Delegate;" Or is there something like "import cs3.utils.Delegate;" ?

            Thanks.
            • 3. Re: How to have constructor wait for xml to load
              puponpup Level 1
              This didn't work. I called four classes, each with xml information that gets loaded. And yet their trace statements go out of order.

              Here's the calls:
              var nav:MainNavigation = new MainNavigation();
              var cal:CalendarOverview = new CalendarOverview();
              var newClass:CookingClass = new CookingClass(-1);
              var classInFile:CookingClass = new CookingClass(1);

              Here's the output:
              Empty class: Enter Title: Enter Description

              Navigation: Front Page News,Chef,Calendar,Six Spices,Concept,Media,Contact,Sample Recipe

              Calendar Overview: May 3rd - Signing: Whole Foods (NJ),May 19th - Class: Willy Street Co-op

              Cooking Class Info: Enter Title: Enter Description,Tangy Chicken: Chicken marinated with fresh herbs and spices, later grilled out-doors or in oven. This dish is a simple variation from regular Indian Tandoori chicken. A simple and tasty chicken for summer gatherings.,Indian Vegetarian Burger: Looking for simple yet tasty burger for your vegetarian guest, you do not have to run to your grocery store. Prepare this burger patty at home with mashed potatoes, paneer (Indian homemade cheese), vegetables, fresh cilantro, ginger and Indian spices. A treat for you and your guests.,Srikhand (Yogurt-Cheese Pudding): A dessert prepared with home made yogurt cheese, flavored with saffron, nutmeg, almonds and pistachio nuts. In hot summer days serve this dessert with fresh fruits on the side.

              Also note: For some reason "Enter Title: Enter Description" gets put as the first Menu Item in the Cooking Class Info. The only reason I could possibly think for this is that somehow newClass and classInFile are intercommunicating. As you can see in the code below "Enter Title: Enter Description" could not possibly be called in an instance of the CookingClass class that has xml information. Also, if I take out the line with "Enter Title: Enter Description" it disappears from both outputs.
              • 4. Re: How to have constructor wait for xml to load
                Level 7
                puponpup,

                >> Sweet! That looks nice. One question, if I'm using Flash CS3 (though
                >> set to AS2) should I still do "import mx.utils.Delegate;" Or is there
                >> something like "import cs3.utils.Delegate;" ?

                You only need the Delegate class in AS2 if you actually use it. In my
                sample code -- which was obviously sparse -- I used it in order to re-route
                the scope of the XML.onLoad event handler. Scoping issues are different in
                AS3, which you can read about in the "Method closures" heading of this
                article:

                http://www.adobe.com/devnet/actionscript/articles/actionscript3_overview.html

                The package for Delegate is mx.utils, regardless of your version of
                Flash. :)

                > This didn't work. I called four classes, each with xml information
                > that gets loaded. And yet their trace statements go out of order.

                I have to admit, I get lost pretty quickly while reading through your
                output examples. There's a lot to read, and in addition, I haven't ever
                used (or heard of) the com.sixspices.updater.model package, which I'm
                guessing defines the XMLMethods class referenced in your code (e.g.,
                XMLMethods.getXMLDocument(), XMLMethods.getImportantNode()). These
                methods -- particularly getXMLDocument() -- may very well come with their
                own built-in load event handlers, so it's hard to say what's getting
                triggered when.

                The apparent complexity of your code definitely merits some
                troubleshooting at this point. For example, the setVenueName(),
                setTimeOfDay(), and setDate() methods (just to name a few) are all foreign
                to me. I have no idea what they do (these are presumably part of that
                com.sixspices package, or maybe additional classes of your own). There's a
                lot going on here, and it may help you to break down your goals into smaller
                sub-goals. I do this all the time, as part of my daily workflow.
                Troubleshooting is a powerful tool! Make small proofs-of-concept, then
                build on those, taking small steps along the way.

                I do see that you have a trace() statement inside your xmlHandler()
                function, and that this trace() statement follows after your
                setInformationFromXML() call. This tells me that anything that might invoke
                a trace() of its own in the setInformationFromXML() method will get traced
                *before* the trace() statement you put yourself. Offhand, it looks like
                that may be exactly what's happening in your output example.


                David Stiller
                Adobe Community Expert
                Dev blog, http://www.quip.net/blog/
                "Luck is the residue of good design."


                • 5. Re: How to have constructor wait for xml to load
                  puponpup Level 1
                  I wrote all the methods and classes in com.sixspices.updater.model - I know they all work separately (I didn't include them because I figured they would just add confusion). The only trace statements are the ones you can see (in the xmlHandler method). The point of the output code (the thing that was supposed to stand out) is the order of the four classes that are instantiated:

                  1). Navigation
                  2). Calendar Overview
                  3). New Class (empty cooking class information)
                  4). Class in file (cooking class with information)

                  The output should be in that order, however, as I posted, it is in this order:
                  1). Empty (new) class
                  2). Navigation
                  3). Calendar Overview
                  4). Cooking class info (class in file)

                  I am guessing that even with the Delegate use, and the xmlHandler method, it is not waiting for the xml file to load but going on to the next class instantiation. This makes sense because the trace statements (output) are in order of how much information is in the xml files, not when they were instantiated.

                  Sorry if my original (or this posting) is confusing. I guess my question is, are you positive that the use of the Delegate class will force the line using it to wait until the xml file is loaded? Because it seems like the line:
                  calendarEvents_xml.onLoad = Delegate.create(this, xmlHandler);
                  - is just saying then when the xml file loads, call the Delegate class. What I need, is for the program not to move on until the xml file loads.
                  • 6. Re: How to have constructor wait for xml to load
                    Level 7
                    puponpup,

                    > I wrote all the methods and classes in com.sixspices.updater.model

                    Aha! That helps! :)

                    > Sorry if my original (or this posting) is confusing.

                    No worries. The only problem with complex/code-heavy posts is that
                    they're often hard to follow (for me, anyway) without the benefit of the
                    full codebase ... and I agree, the full content of the sixspices package
                    would likely have added even more to my confusion.

                    > I guess my question is, are you positive that the use of the Delegate
                    > class
                    > will force the line using it to wait until the xml file is loaded?

                    Oh, gosh ... no! Delegate doesn't even *begin* to do that. I'm sorry
                    if my previous posts made it seem like Delegate was a solution to your
                    question. What Delegate does (in AS2) is allow you to re-route the focus of
                    a function's scope -- that is, its point of view -- it doesn't have anything
                    to do with timing or waiting for data to load.

                    > Because it seems like the line:
                    > calendarEvents_xml.onLoad = Delegate.create(this, xmlHandler);
                    > - is just saying then when the xml file loads, call the Delegate class

                    That's right. Assuming your static sixspices methods don't have
                    XML-related event handlers of their own, then that XML.onLoad event will
                    fire when the XML data have loaded. When that happens, the xmlFunction will
                    be executed. You could just as easily write it like this:

                    calendarEvents_xml.onLoad = xmlHandler;

                    ... and if you did, then any reference to the keyword "this" (without
                    quotes) would refer to calendarEvents_xml itself, because that's how scoping
                    works with event handlers in AS2. The Delegate.create() method simply
                    allows you to rescope what "this" refers to in the function reference. With
                    create(), any reference to "this" inside the xmlHandler() will refer to the
                    class in which this event handler appears.

                    > What I need, is for the program not to move on until the xml file loads.

                    That's why I suggested something like an init2() method inside that
                    xmlHandler() function. Whatever you want paused -- put it inside init2().
                    That init2() method doesn't get called until xmlHandler() fires.

                    Does that make sense?


                    David Stiller
                    Adobe Community Expert
                    Dev blog, http://www.quip.net/blog/
                    "Luck is the residue of good design."


                    • 7. How to have constructor wait for xml to load
                      puponpup Level 1
                      >> What I need, is for the program not to move on until the xml file loads.

                      >That's why I suggested something like an init2() method inside that
                      >xmlHandler() function. Whatever you want paused -- put it inside init2().
                      >That init2() method doesn't get called until xmlHandler() fires.

                      The problem with this approach, is it's not good object-oriented programming. There's not just one line I want
                      paused, I want the whole program paused until this information gets loaded. If the information takes a long time to
                      load, I don't want the rest of the program to load because it would be confusing for the user to see a page without
                      any important content on it and they might try to click away before the content does eventually load. I need to be
                      able to figure out whether the xml content has loaded from outside the class so I could so something like this and
                      make sure that loadCalendarDesign() doesn't get called until it's xml data has loaded:
                      • 8. Re: How to have constructor wait for xml to load
                        Level 7
                        puponpup,

                        > The problem with this approach, is it's not good object-
                        > oriented programming.

                        Huh? Why not? If your class hides hides the waiting mechanism, that's
                        a *good* thing.

                        > There's not just one line I want paused, I want the whole
                        > program paused until this information gets loaded.

                        Why not have your class dispatch a "load" event?

                        > it would be confusing for the user to see a page without
                        > any important content on it and they might try to click
                        > away before the content does eventually load.

                        I agree with that. So either write your class so that it doesn't load
                        the XML itself -- in other words, it gets passed a fully loaded XML
                        instance -- or have it dispatch an event when the XML it loads has fully
                        downloaded.

                        > I need to be able to figure out whether the xml content has
                        > loaded from outside the class so I could so something like
                        > this and make sure that loadCalendarDesign() doesn't get
                        > called until it's xml data has loaded:

                        Yeah, sounds like a job for a custom event.

                        Here's a quick overview:

                        http://www.quip.net/blog/2006/flash/actionscript-20/how-to-raise-events-eventdispatcher


                        David Stiller
                        Adobe Community Expert
                        Dev blog, http://www.quip.net/blog/
                        "Luck is the residue of good design."


                        • 9. Re: How to have constructor wait for xml to load
                          puponpup Level 1
                          >Huh? Why not? If your class hides hides the waiting mechanism, that's
                          >a *good* thing.

                          I just meant since the next step in the program is not part of the class that's getting the xml so putting the "view" aspect in the "model" class would be bad OOP since the rest of the view aspects are in a separate class. Though obviously I wasn't clear about that :-)

                          >Yeah, sounds like a job for a custom event.

                          Sounds like the way to go, though events make my mind go all woozy.

                          Oh well. Thanks!