9 Replies Latest reply on Jul 29, 2009 10:06 AM by cyber0897

    Flash builder 4, Global Variables... help :)

    cyber0897 Level 1

      hey guys, im new to this form and to flex, so if this post is in the wrong place i appologise.

       

      I have searched the internet for this issue but i have not found a good solution. The only solution i found ended up in errors that i could not get around.

       

      Basically waht im trying to do is, build a class containing variables which can be accessed throughout my project ( as in components ).

       

      the basic structure im workign with is:

      1. starts out with a login page in states

      2. onsuccessful login, i get to the main page.

      3. i use webservice to get all the information from the server to populate in the datagrid fields.

       

      basically i want this information available throughout my project.

       

      if anyone can help me with this, i would greately appretiate it!!

       

      the code i found on the internet goes something like this.

       

      in a file called global.as i have the following code in the mainScript folder (mainScript/global.as)

      package mainScript{
          public class globalVars{
              public static const var siteUrl:String = "google.com";
          }
      }

       

      and in my main application i have

       

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"
              xmlns:PageEditor="modules.PageEditor.*"
              xmlns:PanelEditor="modules.PanelEditor.*"
              xmlns:SiteEditor="modules.SiteEditor.*"
              xmlns="*"
              initialize="init()">
             
              <fx:Script>
                  <![CDATA[
                      import mainScript.globalVars;
                      import mx.controls.Alert;
                      public function init():void{
                          Alert.show("here");
                          Alert.show(mainScript.globalVars.siteUrl);
                      }
                  ]]>
              </fx:Script>
                      <mx:Panel id="mainForm" width="220" height="100%" backgroundAlpha=".20">
                      <mx:VDividedBox width="200" height="100%" backgroundAlpha=".20">
                     
                          <mx:DataGrid id="siteSelected"    width="100%"
                                                          height="100%"
                                                          backgroundAlpha=".8"
                                                          borderStyle="none"
                                                          backgroundColor="#333333"
                                                          rollOverColor="haloOrange"
                                                           dataProvider="{}" >
                              <mx:columns>
                                  <mx:DataGridColumn dataField="name" headerText="Sites" />
                              </mx:columns>
                          </mx:DataGrid>
                         
                          <mx:DataGrid id="pram" width="100%" height="100%"
                                                          visible="false" backgroundAlpha=".40">
                              <mx:columns>
                                  <mx:DataGridColumn dataField="name" headerText="Modules" />
                              </mx:columns>
                          </mx:DataGrid>
                         
                      </mx:VDividedBox>
                  </mx:Panel>
                  <mx:Panel id="dataPanel" width="840" height="100%" backgroundAlpha=".20" visible="false">
                      <mx:ViewStack width="100%" height="100%" id="myViewStack"  >
                          <PageEditor:PageEditor id="PageEditor" />
                          <PanelEditor:PanelEditor id="PanelEditor" />
                          <SiteEditor:SiteEditor id="SiteEditor" />
                      </mx:ViewStack>
                  </mx:Panel>
      </s:Application>

       

       

       

      unfortunately i get 1 error in this code. the error states: "1202: Access of undefined property globalVars in package mainscript."

       

       

      if someone could help me solve this error, or help me with a different solution i would really appretiate it. I am completely stuck here...

       

      thanks a lot in advance

        • 1. Re: Flash builder 4, Global Variables... help :)
          SunilAdobe Adobe Employee

          Try renaming the file to the same name of the class i.e. to globalVars.as (and also I think the complier does not like static and const together, remove const)

           

          -Sunil

          • 2. Re: Flash builder 4, Global Variables... help :)
            mjonkman

            Hi

             

            Your filename must match your class name:

             

            package mainScript{

            public class globalVars{

            public static const siteUrl:String = "google.com";

            }

            }

             

            should be in a file globalVars.as in the mainScript directory in your source folder.

             

            also

            your example shows:

            public static const var siteUrl:String = "google.com";

             

            either you have a constant or you have a variable but you don't have a "const var".

            • 3. Re: Flash builder 4, Global Variables... help :)
              cyber0897 Level 1

              ohhhh alrit great im going to try both of the suggestions... thanks a lot guys...

              • 4. Re: Flash builder 4, Global Variables... help :)
                mjonkman Level 1

                Hi

                 

                Just to be clear, both const and var can be prefixed with static. Static means its a class property and is accessed directly through a class reference. const means a constant unchanging, var means its a variable. A static const should be a constant on the class. static var should be class variable. What you can't do however, is have a "const var" that should have thrown a compiler error.

                 

                Sincerely

                Mark R. Jonkman

                • 5. Re: Flash builder 4, Global Variables... help :)
                  cyber0897 Level 1

                  YESS!!!! THAT WORKED LIKE A CHAMP!!

                  thank you soo much guys... i really appretiate it...

                  i just have one more problem and them im all set...

                  i made the following changes to the code and renamed the file to mainList.as

                  package mainScript{
                      import mx.collections.ArrayCollection;
                      import mx.controls.Alert;
                      import mx.rpc.events.FaultEvent;
                      import mx.rpc.events.ResultEvent;
                     
                      import services.main.Main;
                      import services.main.*;

                   

                      public class mainList{
                          // variables
                          [Bindable] public var sourceData:ArrayCollection;
                          public static var mainListData:ArrayCollection;
                         
                          // Web services
                          public var mainInfo:Main = new Main();
                         
                          public static function initializeGetList():void{
                              getAllSites();
                          }
                         
                          public function getAllSites():void{
                              mainInfo.addEventListener(ResultEvent.RESULT, listener);
                              mainInfo.addEventListener(FaultEvent.FAULT, fault);
                              mainInfo.GetSiteList();
                          }
                          public function listener(event:ResultEvent):void{
                              sourceData = event.result as ArrayCollection;
                              mainListData = event.result as ArrayCollection;
                          }
                          public function fault(event:FaultEvent):void{
                              Alert.show(event.fault.faultDetail);
                          }
                      }
                  }

                   

                  what im trying to do is i need to call the function getAllSites() as soon as the application is running, but when i try doing "public static function getAllSites():void" it gives me an error saying "Access to undefined property fault" "access to undefined property listener" "access to undefined prperty mainInfo".

                  i was wondering what exactly the problem is??

                   

                   

                  again thank you guys sooo much for all your help!! i really appretiate it!!  and also thanks for the clarification... i sota knew that i couldnt have a static and a const in the same line but i saw someone else do it in their example so i thought i might give it a try...

                  but once i made the changed you guys suggested it worked like champ!!!

                  • 6. Re: Flash builder 4, Global Variables... help :)
                    mjonkman Level 1

                    Hi

                     

                    You can have static and const in the same line.

                     

                    That aside, what you have for code is a bit nightmarish.

                     

                    First:

                    static means its a class property or function thus you will always prefix it with the class name when accessing it, the exception of course when your inside the class, but its often better to prefix things for clarity.

                     

                    Next, a static method cannot call an instance method (those not prefixed by "static")

                     

                    Thus if you look at your code you have:

                     

                    public static function initializeGetList():void{

                    getAllSites();

                    }

                     

                    public function getAllSites():void{

                    mainInfo.addEventListener(ResultEvent.RESULT, listener);

                    mainInfo.addEventListener(FaultEvent.FAULT, fault);

                    mainInfo.GetSiteList();

                    }

                     

                    you have a static (class method) called initializeGetList() it is attempting to call an instance method named "getAllSites()" this will fail and I would have expected a compiler error.

                     

                    What exactly are you trying to accomplish? Are you actually creating a Flex app, is this an ActionScript application?

                     

                    If you want to create something that will hold a few "global" variables and methods, creating a class that holds them as static variables and methods is one route you can go. The Math class is an example of that. But if you go that route, treat it as if it were exactly that - static methods and variables, don't mix in instance methods into the class as well since you would have to create an instance of the class, store it in a variable and then call the method on the instance.

                     

                    Sincerely

                    Mark R. Jonkman

                    • 7. Re: Flash builder 4, Global Variables... help :)
                      cyber0897 Level 1

                      hey mjonkman, what im trying to acomplish here is that i want a function inside of that package getAllSites() to initialize as soon as the application is loaded (getAllSites() is basically a webservice call im doing using the interospection wizard) once the getAllSites goes thru i need the variable sourceData to be globally accessable, this variable is later going to be binded in a datagrid.

                      this is all the code i have for right now...

                       

                      in the mainList.as i have:

                      // ActionScript file
                      package mainScript{
                          import mx.collections.ArrayCollection;
                          import mx.controls.Alert;
                          import mx.rpc.events.FaultEvent;
                          import mx.rpc.events.ResultEvent;
                         
                          import services.main.*;

                       

                          [Bindable] public class mainList{
                              // variables
                              public static var sourceData:ArrayCollection;
                             
                              // Web services
                              public static var mainInfo:Main = new Main();
                             
                              public static function getAllSites():void{
                                  mainInfo.addEventListener(ResultEvent.RESULT, listener);
                                  mainInfo.addEventListener(FaultEvent.FAULT, fault);
                                  mainInfo.GetSiteList();
                              }
                              public static function listener(event:ResultEvent):void{
                                  sourceData = new ArrayCollection(event.result as Array);
                                  //sourceData = event.result as ArrayCollection;
                                  Alert.show("done");
                              }
                              public static function fault(event:FaultEvent):void{
                                  Alert.show(event.fault.faultDetail);
                              }
                          }
                      }


                      ------------------------------------------------------------------------------------------ -------

                       

                      and in the mainWindow.mxml i have

                       

                      <?xml version="1.0" encoding="utf-8"?>
                      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"
                              xmlns:PageEditor="modules.PageEditor.*"
                              xmlns:PanelEditor="modules.PanelEditor.*"
                              xmlns:SiteEditor="modules.SiteEditor.*"
                               initialize="mainScript.mainList.getAllSites()">
                             
                              <fx:Script>
                                  <![CDATA[
                                      import mx.collections.ArrayCollection;
                                      import mainScript.mainList;
                                      import mainScript.global;
                                      import mx.controls.Alert;
                                      [Bindable] public var mainListData:ArrayCollection = mainScript.mainList.sourceData;
                                  ]]>
                              </fx:Script>
                                      <mx:Panel id="mainForm" width="220" height="100%" backgroundAlpha=".20">
                                      <mx:VDividedBox width="200" height="100%" backgroundAlpha=".20">
                                     
                                          <mx:DataGrid id="siteSelected"    width="100%"
                                                                          height="100%"
                                                                          backgroundAlpha=".8"
                                                                          borderStyle="none"
                                                                          backgroundColor="#333333"
                                                                          rollOverColor="haloOrange"
                                                                          dataProvider="{mainListData}" >
                                              <mx:columns>
                                                  <mx:DataGridColumn dataField="name" headerText="Sites" />
                                              </mx:columns>
                                          </mx:DataGrid>
                                         
                                          <mx:DataGrid id="pram" width="100%" height="100%"
                                                                          visible="false" backgroundAlpha=".40">
                                              <mx:columns>
                                                  <mx:DataGridColumn dataField="name" headerText="Modules" />
                                              </mx:columns>
                                          </mx:DataGrid>
                                         
                                      </mx:VDividedBox>
                                  </mx:Panel>
                                  <mx:Panel id="dataPanel" width="840" height="100%" backgroundAlpha=".20" visible="false">
                                      <mx:ViewStack width="100%" height="100%" id="myViewStack"  >
                                          <PageEditor:PageEditor id="PageEditor" />
                                          <PanelEditor:PanelEditor id="PanelEditor" />
                                          <SiteEditor:SiteEditor id="SiteEditor" />
                                      </mx:ViewStack>
                                  </mx:Panel>
                      </s:Application>


                      ------------------------------------------------------------------------------------------ -------------------------------------------

                       

                      as you can see in the mainList.as i made a few changes, like i made all the functions static so i can access them in my mainWindow.mxml

                       

                      i also made my class bindable so i can stick it in the datagrid.

                       

                      the problem im having is that... it calles the getAllSites() just fine but unfortunately the datagrid is not populating.

                       

                      I was wondeing if anyone can tell me why.....

                       

                      and again thanks for the fast reply guys!!

                      • 8. Re: Flash builder 4, Global Variables... help :)
                        mjonkman Level 1

                        Hi

                         

                        I'm guessing that you are then doing a Flex app proper ie. you have an MXML application class. It would probably be better for you to write your initialization code into your main application class then to attempt to work with the approach you are taken.

                         

                        The rationale for this statement is this:

                         

                        Class based code is initialized immediately as the class is loaded during the preload of the application. Thus your statement:

                         

                        public static var mainInfo:Main = new Main();

                         

                        will execute as soon as your mainList class is loaded. I don't know how much organization the compiler does in terms of optimizing compile order for classes but a construct like that would most likely attempt to run even before your application has executed its constructor function. When Flex compiles the swf, it places all the classes on Frame 1, then after successful load of Frame 1 and all RSL libraries it executes Frame 2 which includes instantiating the Flex application. What you have above might work, but I'd personally be a little nervous of attempting to execute code prior to entry into frame 2.

                         

                        I often write a "code behind" file for my MXML. That is I create an .as class that extends Application.

                         

                        Say:

                         

                        src/core/MyAppBase.as

                         

                        then in the MXML file I add a new namespace:

                         

                        xmlns:core="core.*"

                         

                        and change <s:Application> to <core:Application>

                         

                        Then I have access immediate access to the constructor of the application, that would be the point I would begin loading the data from the WebService, and on successful completion of that set the appropriate global variables. I would design my application with a starting state or view that indicated data loading in some form. Then I would key off FlexEvent.APPLICATION_COMPLETE event to call the webservice to load the data and in the result handler, populate the global variables in question, and move on to displaying the content (assuming the content depends on the results of the webservice).

                         

                        in my MyAppBase constructor

                         

                         

                        public function MyAppBase()

                        {

                        addEventListener(FlexEvent.APPLICATION_COMPLETE, handleApplicationComplete);

                        }

                         

                        protected function handleApplicationComplete(pEvent:FlexEvent):void

                        {

                        // create the service instance, set the result and fault handlers

                        var mainInfo:Main = new Main();

                        mainInfo.addEventListener(ResultEvent.RESULT, handleServiceResult);

                        mainInfo.addEventListener(FaultEvent.FAULT, handleServiceFault);

                        mainInfo.GetSiteList();

                        }

                         

                        protected function handleServiceResult(event:ResultEvent):void

                        {

                        mainList.sourceData = new ArrayCollection(event.result as Array);

                        Alert.show("done");

                         

                        // remove the listener reference from the Main instance and get rid of the Main instance

                        // if I'm not going to use it again.

                        }

                         

                        protected function handleServiceFault(event:FaultEvent):void

                        {

                        Alert.show(event.fault.faultDetail);

                         

                        // remove the listener reference from the Main instance and get rid of the Main instance

                        // if I'm not going to use it again.

                        }

                         

                        alternatively, you could keep your static methods for event handling as you currently have it in your mainList class but alter it so that calling getAllSites() instantiates the service and sets up the listeners and calls the

                        method all at once calling getAllSites() from either the constructor of the application or the applicationComplete handler.

                         

                        public static function getAllSites():void

                        {

                        mainInfo = new Main();

                        mainInfo.addEventListener(ResultEvent.RESULT, listener);

                        mainInfo.addEventListener(FaultEvent.FAULT, fault);

                        mainInfo.GetSiteList();

                        }

                         

                        The decision is largely up to you and how you construct your application. Its probably a personal preference on my part to make the calls in the application, load the data, store it in the "global variable" vs. writing a lot of static functions as event handlers.

                         

                        Sincerely

                        Mark R. Jonkman

                        • 9. Re: Flash builder 4, Global Variables... help :)
                          cyber0897 Level 1

                          ur probably right... i think imona take the approach that you suggested.., btu over and all i got everythign working like a champ!! thanks soo much guys!! relaly appretiate it!