6 Replies Latest reply on Jan 21, 2011 6:49 PM by kogare

    no binded data on first call

    kogare

      i'm new in flex and i've question about data/services in flash builder.

      i've air application that calling another component. i add button to call function from that component but it seems the return data from the function call is missing on the first call but not after that. here's my code snippet

       

      mainapp

          <fx:Script>
             
              <![CDATA[
                  import mx.controls.Alert;


                  public var accountCollection:AccountData = new AccountData();
                 
                  public var num:String;

                  protected function button1_clickHandler(event:MouseEvent):void
                  {
                      Alert.show(accountCollection.getNumAccount(), "Error", Alert.OK, this, null, null, Alert.OK);
                  }

              ]]>
             
          </fx:Script>
         
          <fx:Declarations>
             
          </fx:Declarations>
         
          <s:Button includeIn="CompanyDetail" x="166" y="516" label="Button" click="button1_clickHandler(event)"/>

       

      mycomponent

      <?xml version="1.0" encoding="utf-8"?>
      <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:centappservices="services.centappservices.*">
         
          <fx:Script>
             
              <![CDATA[
                 
                  import mx.controls.Alert;
                  import mx.rpc.events.FaultEvent;
                  import mx.rpc.events.ResultEvent;
                 
                  import valueObjects.NumAccount;
                 
                  private var numAcc:NumAccount = new NumAccount();
                 
                  public function getNumAccount():String
                  {
                      getNumAccountResult.token = centAppServices.getNumAccount();
                      getNumAccountResult.addEventListener(ResultEvent.RESULT, getNumAccountResult_resultHandler);
                      getNumAccountResult.addEventListener(FaultEvent.FAULT, getNumAccountResult_faultHandler);
                      return numAcc.count;
                  }           

                  public function getNumAccountResult_resultHandler(event:ResultEvent):void
                  {
                      numAcc = getNumAccountResult.lastResult[0] as NumAccount;
                  }

                  public function getNumAccountResult_faultHandler(event:FaultEvent):void
                  {
                      Alert.show(event.fault.faultString, "Fault Information");
                  }

              ]]>
             
          </fx:Script>
         
          <fx:Declarations>
             
              <s:CallResponder id="getNumAccountResult"
                               result="getNumAccountResult_resultHandler(event)"
                               fault="getNumAccountResult_faultHandler(event)"/>
              <centappservices:CentAppServices id="centAppServices" fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)" showBusyCursor="true"/>
             
          </fx:Declarations>
         
      </s:Group>

      when i click the button it show there's nothing in the alert box but when i click it again the value appeared. any suggestion?

       

      thank you

        • 1. Re: no binded data on first call
          Gaurav J Adobe Employee

          When you click the button for the first time, that's when you call centAppServices.getNumAccount();so numAcc is not populated with the results at that time.

           

           

          -Gaurav

          http://www.gauravj.com/blog

          • 2. Re: no binded data on first call
            kogare Level 1

            i've used debug and i know that its not yet populated when the first time i clicked the button. maybe its my wrong understanding, my understanding is like this:

             

            public function getNumAccount():String
                        {

                            ---> start calling data/services and populate

                            getNumAccountResult.token = centAppServices.getNumAccount();
                            getNumAccountResult.addEventListener(ResultEvent.RESULT, getNumAccountResult_resultHandler);
                            getNumAccountResult.addEventListener(FaultEvent.FAULT, getNumAccountResult_faultHandler);

                            ---> end ---> the numAcc should be already populated after this?

             

                            return numAcc.count;
                        }

             

            i fixed it by calling the function first in the creationcomplete and then return the value when i click the button.

             

            public function getNumAccount():void
                        {
                            getNumAccountResult.token = centAppServices.getNumAccount();
                            getNumAccountResult.addEventListener(ResultEvent.RESULT, getNumAccountResult_resultHandler);
                            getNumAccountResult.addEventListener(FaultEvent.FAULT, getNumAccountResult_faultHandler);
                        }

             

            public function getNum():NumAccount {
                            return numAcc;
                        }

             


            follow up question. it works when i seperate the function call (one in the creation complete and the other one in the clickhandler) but when i join the function call to clickhandler only, it only populate the data on the second time i click it.

             

            because logicly thinking:

            // call data/services and populate data

            protected function window1_creationCompleteHandler(event:FlexEvent):void
                        {
                            accountCollection.getNumAccount();
                        }

             

            // show data

            protected function button1_clickHandler(event:MouseEvent):void
                        {
                            num = accountCollection.getNum();
                            Alert.show(num.count, "Error", Alert.OK, this, null, null, Alert.OK);
                        }

             

            ----> is the same one with this one --->

            protected function button1_clickHandler(event:MouseEvent):void
                        {
                           // call data/services and populate data
                            accountCollection.getNumAccount();
                           // show data
                            num = accountCollection.getNum();
                            Alert.show(num.count, "Error", Alert.OK, this, null, null, Alert.OK);
                        }

             

            am i right?

             

            thank you for the answer so far =)

            • 3. Re: no binded data on first call
              superkatakam

              i believe the function you're calling is a service call. therefore, flex doesnt wait for your result to come out from the service call to go to the next step.

              the result i'm sure you're seeing is the result you've obtained on your previous click.

              i suggest you use an asyncToken to solve this.

               

              Here is an example as to how an asyncToken works.

               

               

              <?xml version="1.0" encoding="utf-8"?> 
              <mx:Application creationComplete="onCreationComplete()" 
              xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
              <mx:Script>
              <![CDATA[
                  import mx.rpc.remoting.RemoteObject;
                  import mx.rpc.events.ResultEvent;
                  import mx.rpc.events.FaultEvent;
                  import mx.rpc.http.mxml.HTTPService;
                  import mx.rpc.AsyncRequest;
                  import mx.rpc.AsyncResponder;
                  import mx.rpc.AsyncToken;
                  import mx.collections.ArrayCollection;
                  import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
                  import mx.controls.AdvancedDataGrid;
                  import mx.controls.Alert;
                  import mx.rpc.IResponder;


                  [Bindable]
                  public var dataList:ArrayCollection;

                  public function getResults(source:String) : ArrayCollection {
                  var ac:ArrayCollection = new ArrayCollection();
                  var data:Array = source.split('#');
                  for (var i:int = 0; i < data.length; i += 3) {
                  var dataObj:Object = {row: data[i], column: data[i+1], value: data[i+2]};     
                  ac.addItem(dataObj)
                  }

                  return ac;
                  }
                  public function result(event:ResultEvent):void{
                  dataList = getResults( String(event.result) );
                  }
                  public function fault(event:FaultEvent) : void {
                  dataList = getResults(String(event.fault)); 
                  }

              public function onCreationComplete():void
              {
              var service:HTTPService = new HTTPService();
              service.url = "http://10.15.20.75/server4flex/servlet/Datagen";
              service.resultFormat = "text";
              var token:AsyncToken = service.send(dataList);
              token.addResponder(new mx.rpc.Responder(result, fault));
              }

              ]]>
              </mx:Script>
              <mx:AdvancedDataGrid id="dg"
              dataProvider="{result}"  
              liveScrolling="true"  
                 
              x="10" y="10" width="621"
                 
              verticalScrollPolicy="on"
              >
                     
              <mx:columns>
                                 
              <mx:AdvancedDataGridColumn dataField="row"
                        
              headerText="Riga"/>
                                 
              <mx:AdvancedDataGridColumn dataField="column"
                        
              headerText="Colonna"/>
                                 
              <mx:AdvancedDataGridColumn dataField="value" 
                        
              headerText="Valore"/>
                     
              </mx:columns>
              </mx:AdvancedDataGrid>

              </mx:Application>

               

               

              or there is another way to do this.

              try using a custom event and trigger the event in actionscript with a responder for it. Thats a successful approach too.

              If this post helps, please mark it

              1 person found this helpful
              • 4. Re: no binded data on first call
                kogare Level 1

                do you have example on your second suggestion, creating custom event and trigger?

                i've tried asynctoken and used php file as services.url, but i don't like the fact that i have to create a php page to represent my data, i want to reduces as many php as i can and use build in flex solution instead if i could.

                 

                thanks

                • 5. Re: no binded data on first call
                  superkatakam Level 1

                  In that case, you dont need a custom event and responder.

                  If you are using a remote object, then your code becomes as follows

                   

                  var responder:Responder  = new Responder(ResultHandler,FaultHandler);

                  var token:AsyncToken = remoteObjectFunction(inParameter);

                  token.addResponder = (responder);

                   

                  public function ResultHandler(event:ResultEvent):void {

                  var ac:ArrayCollection = event.result as ArrayCollection;

                  .

                  .

                  .

                   

                  }

                   

                  public function FaultHandler(event:FaultEvent):void {

                  Alert.show("Fault Event occured");

                  .

                  .

                  .

                  }

                   

                  what kind of data you get to the result handler can vary depending on what you make. like a list becomes an arrayCollection or an xml file can be retrieved here as XML;

                  so the rest is up to you.

                   

                  or if you are using httpService, then you need to give it a url. thats imperative

                   

                  then your code changes to

                   

                  var token:AsyncToken = servicefunction.send();

                   

                  I think you can handle the rest

                  • 6. Re: no binded data on first call
                    kogare Level 1

                    @superkatakam

                    i've tried running the code with your suggestion asynctoken, but the result still the same one, the data isn't there when i clicked it first time

                    here's my code snippet, i believe its already the same one with what you're thinking (if not tell me =D)

                     

                    theData

                     

                    <?xml version="1.0" encoding="utf-8"?>
                    <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
                             xmlns:s="library://ns.adobe.com/flex/spark"
                             xmlns:mx="library://ns.adobe.com/flex/mx"
                             xmlns:centappservices="services.centappservices.*">
                       
                        <fx:Script>
                           
                            <![CDATA[
                                import mx.collections.ArrayCollection;
                                import mx.controls.Alert;
                                import mx.rpc.AsyncToken;
                                import mx.rpc.Responder;
                                import mx.rpc.events.FaultEvent;
                                import mx.rpc.events.ResultEvent;
                               
                                import valueObjects.Company;
                               
                                private var companyData:Perusahaan = new Company();
                                private var token:AsyncToken;
                                   
                                protected function centAppServices_faultHandler(event:FaultEvent):void
                                {
                                    Alert.show(event.fault.faultString, "Fault Information");
                                }           
                               
                               
                                public function getCompany():void
                                {
                                    var responder:mx.rpc.Responder = new mx.rpc.Responder(resultHandler, faultHandler);
                                    token = centAppServices.getCompany();
                                    token.addResponder(responder);
                                }
                               

                                protected function faultHandler(event:FaultEvent):void
                                {
                                    Alert.show(event.fault.faultString, "Fault Information");
                                }


                                protected function resultHandler(event:ResultEvent):void
                                {
                                    companyData = event.result[0] as Company;
                                }
                               
                               
                                public function getCompanyData():Company{
                                    return companyData;
                                }

                            ]]>
                           
                        </fx:Script>
                       
                        <fx:Declarations>
                                   
                            <centappservices:CentAppServices id="centAppServices"
                                                             fault="centAppServices_faultHandler(event)"/>
                           
                        </fx:Declarations>
                       
                    </s:Group>

                     


                    dataCall

                     

                    <?xml version="1.0" encoding="utf-8"?>
                    <s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
                                           xmlns:s="library://ns.adobe.com/flex/spark"
                                           xmlns:mx="library://ns.adobe.com/flex/mx">
                       
                        <fx:Script>
                           
                            <![CDATA[
                                import mx.collections.ArrayCollection;
                                import mx.controls.Alert;
                               
                                import myComponent.CompanyData;
                               
                                import valueObjects.company;
                               
                                public var _internal_companyData:Company= new Company();
                                public var _internal_companyComponent:CompanyData = new CompanyData();
                               
                                public var str:String;
                               

                                protected function button1_clickHandler(event:MouseEvent):void
                                {
                                    _internal_companyComponent.getCompany();
                                    _internal_companyData = _internal_companyComponent.getCompanyData();
                                   
                                    Alert.show(_internal_companyData.klu_spt, "Error", Alert.OK, this, null, null, Alert.OK);
                                }

                            ]]>
                           
                        </fx:Script>
                       
                        <fx:Declarations>
                           
                        </fx:Declarations>
                        <s:Button x="309" y="53" label="Button" click="button1_clickHandler(event)"/>
                       
                    </s:WindowedApplication>

                     

                    i really don't understand what happening.. enlightment please? =(