share data between widgets only works for the first time

5242
13
Jump to solution
12-14-2014 08:52 PM
Ye_FengFeng
New Contributor II

Hi,

I follow the link to share data between widgets : https://community.esri.com/thread/34393

But I can only pass the shared data the first time.

I have Input.widget (widget A) and Records.widget(widget B), and shared object pass from widget A to widget B.

The first time I open widget A and click "OK" button, the data pass to widget B, widget A closed and widget B opened and init() of widget B called.

But the second time when  I open widget A and click "OK" button,widget A closed and widget B opened, but the init() function in widget B not called.

It is because I haven't release widget B when it is reload? How can I solve the issue?

Sorry for the poor English, thank you in advance.

0 Kudos
1 Solution

Accepted Solutions
RobertScheitlin__GISP
MVP Emeritus

Ye Feng Feng,

This is what I have in a working Widget B on one of my Flex Viewer 3.6 sites:

Lines one and two are of course in my widgets init function.

In my functions I am finding the key ParcelAddress and then taking this value and entering it into a textbox on my widget B. I then remove that value from the shared data to acknowledge that I have received and used that value passed from widget A.

AppEvent.addListener(AppEvent.DATA_NEW_PUBLISHED, sharedDataUpdated); 
AppEvent.addListener(AppEvent.DATA_SENT, sharedDataUpdated2);

            private function sharedDataUpdated(event:AppEvent):void
            {
                var dataTable:Hashtable = event.data.data as Hashtable;
                if (dataTable.containsKey("ParcelAddress"))
                {
                    var recAC:ArrayCollection = dataTable.find("ParcelAddress") as ArrayCollection;
                    for (var i:Number = 0; i < recAC.length; i++)
                    {
                        var obj:Object = recAC;
                        var fitm:Object = (useSingleLine)?frmLocateAddress.getChildAt(1):frmLocateAddress.getChildAt(0);
                        var tAddress:Object = fitm.getChildAt(0);
                        tAddress.text = obj.paddress;
                        showStateAddress();
                    }
                    dataTable.remove("ParcelAddress");
                }
            }
            
            private function sharedDataUpdated2(event:AppEvent):void
            {
                var dataTable:Hashtable = event.data as Hashtable;
                if (dataTable.containsKey("ParcelAddress"))
                {
                    var recAC:ArrayCollection = dataTable.find("ParcelAddress") as ArrayCollection;
                    for (var i:Number = 0; i < recAC.length; i++)
                    {
                        var obj:Object = recAC;
                        var fitm:Object = (useSingleLine)?frmLocateAddress.getChildAt(1):frmLocateAddress.getChildAt(0);
                        var tAddress:Object = fitm.getChildAt(0);
                        tAddress.text = obj.paddress;
                        showStateAddress();
                    }
                    dataTable.remove("ParcelAddress");
                }else if(dataTable.containsKey("Deactivate_DrawTool"))
                {
                    setMapAction(null, null, null, null);
                }
            }

So the answer to question 1 is neither it should be:

AppEvent.addListener(AppEvent.DATA_NEW_PUBLISHED, sharedDataUpdated);  
AppEvent.addListener(AppEvent.DATA_SENT, sharedDataUpdated2);

On statement 2, if you use DATA_NEW_PUBLISHED then you need to use event.data.data as Hashtable and when using  DATA_SENT only use event.data as Hashtable.

For the code being messy in your code inserts make sure that the first line of code that you paste has NO SPACES OR TABS at the very beginning of that line when you paste it in. The once you do the syntax formatting you can add tabs and spaces.

View solution in original post

0 Kudos
13 Replies
RobertScheitlin__GISP
MVP Emeritus

Ye Feng Feng,

  A widget init function is only called once (when the config is loaded).

You will notice on the 11th reply in that thread you reference I provide code to Wade that add two listeners:

            private function init():void  
            {  
                trace("MyPrintWidget init()");  
                AppEvent.addListener(AppEvent.DATA_PUBLISH, sharedDataUpdated);  
                AppEvent.addListener(AppEvent.DATA_SENT, sharedDataUpdated2);  
                fetchSharedData();  
            }  
              
            private function sharedDataUpdated(event:AppEvent):void  
            {  
                var data:Object = event.data;                  
                if (data.key == "LayoutTitle")  
                {  
                    var theObj:Object = data.collection[0];  
                    mapproduct = theObj.mapproduct;  
                    maptrait = theObj.maptrait;  
                    title = mapproduct + maptrait;  
                }  
            }  
  
            private function sharedDataUpdated2(event:AppEvent):void  
            {  
                var dataTable:Hashtable = event.data as Hashtable;  
                if (dataTable.containsKey("LayoutTitle"))  
                {  
                    var recAC:ArrayCollection = dataTable.find("LayoutTitle") as ArrayCollection;  
                    var theObj:Object = recAC[0];  
                    mapproduct = theObj.mapproduct;  
                    maptrait = theObj.maptrait;  
                    title = mapproduct + maptrait;  
                }  
            }

You need both listeners.

0 Kudos
Ye_FengFeng
New Contributor II

Hi Robert,

So happy to get response from you. I use exact the same code as in your answer (11th reply in the reference link).

If I use 1 listener (sharedDataUpdated) only, it never pass the parameter to the other widget.

Don't know what is wrong.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ye Feng Feng,

   OK can you attach all you code for review then (both widgets)?

0 Kudos
Ye_FengFeng
New Contributor II

Hello Robert,

I have an urgent meeting now, will post the source code as long as I am back, thank you!

0 Kudos
Ye_FengFeng
New Contributor II

Hi Robert,

So sorry I haven't found how to add an attachment, hence I post the code below (also cannot find how to post in code made,

SearchCustomer.mxml

public static var queryStr:String;

  public function customerInputEvent():void

  {

  queryStr = "SELECT CUSTOMER_NAME, CUSTOMER_IC, CUSTOMER_EMAIL, CUSTOMER_ADDRESS, CUSTOMER_INTEREST FROM dbo.CUSTOMER WHERE ";

  if(userName.text){

  queryStr = queryStr + " CUSTOMER_NAME= '" + userName.text + "'"

  }

  if (userIC.text){

  if (!userName.text){

  queryStr = queryStr + " CUSTOMER_IC= '" + userIC.text + "'"

  }else{

  queryStr = queryStr + " and CUSTOMER_IC = '" + userIC.text + "'"

  }

  }

  if (userEmail.text){

  if ((!userName.text) && (!userIC.text)){

  queryStr = queryStr + " CUSTOMER_EMAIL = " + userEmail.text

  }else{

  queryStr = queryStr + " and CUSTOMER_EMAIL = " + userEmail.text

  }

  }

  if (userAddress.text){

  if ((!userName.text) && (!userIC.text) && (!userEmail.text)){

  queryStr = queryStr + " CUSTOMER_ADDRESS = '" + userAddress.text + "'"

  }else{

  queryStr = queryStr + " and CUSTOMER_ADDRESS = '" + userAddress.text + "'"

  }

  }

  trace("sql Query to be passed to result widget = " + queryStr);

  // share data 

  var queryArr:ArrayCollection = new ArrayCollection(); 

  var queryConfig:Object = {

  sql: String(queryStr)

  };             

  queryArr.addItem(queryConfig); 

  addSharedData("QueryState", queryArr);

  var widgetId:Number = ViewerContainer.getInstance().widgetManager.getWidgetId("Customer Result"); 

  AppEvent.dispatch(AppEvent.WIDGET_RUN, widgetId);

  this.setState("closed");

  }

  }

CustomerResult.mxml

import widgets.Customer.SearchCustomer.SearchCustomer;

  public var getSqlQuery:String;

  public function init():void {

  AppEvent.addListener(AppEvent.DATA_PUBLISH, sharedDataUpdated); 

  AppEvent.addListener(AppEvent.DATA_SENT, sharedDataUpdated2); 

  fetchSharedData();

  Alert.show("query get from customer input = " + getSqlQuery);

  webservice.CustomerDetail(getSqlQuery);

  }

  private function sharedDataUpdated(event:AppEvent):void 

  { 

  var data:Object = event.data;                 

  if (data.key == "QueryState") 

  { 

  var theObj:Object = data.collection[0]; 

  getSqlQuery = theObj.sql; 

  } 

  } 

  private function sharedDataUpdated2(event:AppEvent):void 

  { 

  var dataTable:Hashtable = event.data as Hashtable; 

  if (dataTable.containsKey("QueryState")) 

  { 

  var recAC:ArrayCollection = dataTable.find("QueryState") as ArrayCollection; 

  var theObj:Object = recAC[0]; 

  getSqlQuery = theObj.sql; 

  } 

  }

  public function CustomerDetail(event:ResultEvent):void {

  CustomerDetail.dataProvider = event.result;

  }

  public function fault(event:FaultEvent):void {

  Alert.show(event.toString());

  }

Thank you very much in advance.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ye Feng Feng,

  Change this event listener

from:

AppEvent.addListener(AppEvent.DATA_PUBLISH, sharedDataUpdated);

to:

AppEvent.addListener(AppEvent.DATA_NEW_PUBLISHED, sharedDataUpdated);

Then your sharedDataUpdated to: (notice the event.data.data)

            private function sharedDataUpdated(event:AppEvent):void
            {
                var dataTable:Hashtable = event.data.data as Hashtable;
                if (dataTable.containsKey("QueryState"))
                {
                    var recAC:ArrayCollection = dataTable.find("QueryState") as ArrayCollection; 
                    var theObj:Object = recAC[0];
                    getSqlQuery = theObj.sql; 
                }
            }
0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ye Feng Feng,

  To use attachments and add code block you have to use the advanced editor. You will see the option as a link at the top of a rely "Use advanced editor" when you are NOT in your inbox but have clicked to go to the actual thread. When in the advanced editor you will find a >> button that allows you to wrap text in a code block I like to paste my code in the reply first (Making sure there is not tab in front of my code) and then select the code and go to the >> insert link and choose a syntax (I use javascript for everything).

Ye_FengFeng
New Contributor II

Hi Robert,

Is the function of sharedDataUpdated and sharedDataUpdated2 exactly the same?

I have modified my code according to your answer. The surprise thing is when I use event.data.data instead of event.data, it will cause error and the shared string not pass to the other widget.

So sorry to trouble you again, thousands of thanks.

0 Kudos
RobertScheitlin__GISP
MVP Emeritus

Ye Feng Feng,

   No the two handler functions are not the same. The handler for DATA_NEW_PUBLISHED has to use the event.data.data and the DATA_PUBLISH uses event.data

0 Kudos