PDA

View Full Version : How to get data from onSuccess method of RPC call



Suma
7 May 2009, 6:20 AM
Hi,
I am retrieving the data from database and storing it in a List. In onSuccess method of AsyncCallback i'm able to get the data from List, but outside this the List size i'm getting as 0. Kindly help me how to access that data which is stored in List outside onSuccess method.

dardison
7 May 2009, 11:36 AM
Suma,

Please provide some code that reflects what are you trying to do. Is not clear where the List is defined, and when you say List what class are you talking about.
Not sure if this is a GXT issue or a Java issue.

Suma
7 May 2009, 10:07 PM
Hi,
Here i'm posting my code. In this i want to access the data from list and list2 which is stored in onSuccess method of service call in RPC call(getChrgProxy) in selectionListener of Grid.




package com.palm.idea.client.master;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.extjs.gxt.ui.client.Events;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.Orientation;
import com.extjs.gxt.ui.client.Style.SelectionMode;
import com.extjs.gxt.ui.client.data.BaseListLoadResult;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.ListLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.FieldEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.ListView;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.PagingToolBar;
import com.extjs.gxt.ui.client.widget.VerticalPanel;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.Field;
import com.extjs.gxt.ui.client.widget.form.FieldSet;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;
import com.palm.idea.client.ExampleServiceAsync;
import com.palm.idea.client.model.ChargeSegment;
import com.palm.idea.client.model.VolumeRate;
import com.palm.idea.client.model.VolumeRateDetail;
public class PromotionCriteria extends LayoutContainer {
private VerticalPanel vp = new VerticalPanel();
final ExampleServiceAsync service = (ExampleServiceAsync) Registry.get("service");

RpcProxy rpcProxy;
PagingToolBar toolBar;
ListStore gridStore;
ListStore store=new ListStore();
Grid grid;
FormPanel formPanel = new FormPanel();
FormPanel panel;
ListStore<ChargeSegment> listStore = new ListStore<ChargeSegment>();
ComboBox<ChargeSegment> comboBox = new ComboBox<ChargeSegment>();
List<ChargeSegment> list = new ArrayList<ChargeSegment>();
List<VolumeRateDetail> list2 = new ArrayList<VolumeRateDetail>();

public PromotionCriteria() {
vp = new VerticalPanel();
vp.setHeight(150);
}
@Override
protected void onRender(Element parent, int index) {
System.out.println("starting of onrender..........");
super.onRender(parent, index);
setStyleAttribute("margin", "10px");
FlowLayout layout = new FlowLayout(10);
setLayout(layout);

RpcProxy proxy = getProxy();
BasePagingLoader loader = new BasePagingLoader(proxy);
loader.setRemoteSort(true);
gridStore = new ListStore(loader);
toolBar = new PagingToolBar(10);
toolBar.bind(loader);
loader.load();

ContentPanel cp = new ContentPanel();
cp.setLayout(new FlowLayout(1000));
cp.setFrame(true);
cp.setSize(750, 350);
cp.setPagePosition(240, 120);
cp.setHeading("Volume RateCode -> Promotion Criteria");
cp.setLayout(new RowLayout(Orientation.HORIZONTAL));
final Grid grid = createVolumeRateGrid();
grid.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
grid.getSelectionModel().addListener(Events.SelectionChange,new Listener<SelectionEvent>() {
public void handleEvent(SelectionEvent be) {
panel.setVisible(true);
VolumeRate volumeRate = (VolumeRate)(be.selection.get(0));
String rateCode = volumeRate.get("volRateCode");
System.out.println(rateCode+"$$$$$$$$$$$$$$$$$$$$^^^^^^^^^^^^");
String startdate = volumeRate.get("start");
System.out.println(startdate+"&&&&&&&&&&&&&&&&&&&&***************");
rpcProxy = getRpcProxy(rateCode,startdate);
BaseListLoader listLoader = new BaseListLoader(rpcProxy);
listStore= new ListStore<ChargeSegment>() ;
listLoader.load();
comboBox.getListView().setStore(listStore);
RpcProxy proxy = getChrgProxy(rateCode,startdate);
BaseListLoader loader = new BaseListLoader(proxy);
list2 = new ArrayList<VolumeRateDetail>();
loader.load();
}
});
grid.setStyleAttribute("borderTop", "none");
grid.setBorders(false);
//grid.setAutoExpandColumn("equipId");
grid.setBorders(true);
cp.add(grid, new RowData(1,1));

cp.setButtonAlign(HorizontalAlignment.LEFT);
cp.setBottomComponent(toolBar);

ContentPanel contentPanel = new ContentPanel();
contentPanel.setFrame(true);
contentPanel.setSize(750, 300);
contentPanel.setPagePosition(240, 470);
contentPanel.setHeading("Promotion Criteria Details");
contentPanel.setLayout(new RowLayout(Orientation.VERTICAL));
panel = createForm();
panel.setVisible(false);
contentPanel.add(panel);
vp.add(cp);
vp.add(contentPanel);
add(vp);
layout();
}

private Grid createVolumeRateGrid() {
List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
ColumnConfig column = new ColumnConfig();

column.setId("volRateCode");
column.setHeader("Promotion Criteria");
column.getHeader();
column.setWidth(150);
configs.add(column);

column = new ColumnConfig();
column.setId("volRateCodeDesc");
column.setHeader("Description");
column.setWidth(100);
configs.add(column);

column = new ColumnConfig();
column.setId("start");
column.setHeader("Start Date");
column.setWidth(100);
configs.add(column);

column = new ColumnConfig();
column.setId("end");
column.setHeader("End Date");
column.setWidth(100);
configs.add(column);

System.out.println("on module2");
ColumnModel cm = new ColumnModel(configs);
grid = new Grid(gridStore, cm);
//grid.setLoadMask(true);
grid.setBorders(true);
grid.setWidth("350");
return (grid);
}

private FormPanel createForm(){
formPanel.setHeaderVisible(false);

FlowLayout layout = new FlowLayout(10);
setLayout(layout);

comboBox = new ComboBox<ChargeSegment>();
comboBox.setFieldLabel("Select the Charge Segment to be added");
//comboBox.setName("Select the Charge Segment to be added");
comboBox.setDisplayField("segmentName");
System.out.println("Count of wrkgr::" + listStore.getCount());
comboBox.setStore(listStore);
comboBox.enableEvents(true);
comboBox.setMinChars(1);
comboBox.setEditable(false);
String callClassComboID = comboBox.getId();
System.out.println("ServiceTypeComboID : " + callClassComboID);
comboBox.setItemId(callClassComboID);
comboBox.setView(new ListView<ChargeSegment>() {
@Override
protected ChargeSegment prepareData(ChargeSegment state) {
state.set("segmentName", state.getSegmentName());
return state;
}
});
comboBox.setTriggerAction(TriggerAction.ALL);
formPanel.add(comboBox);

FieldSet fieldSet = new FieldSet();
fieldSet.setHeading("Existing Configurations");
fieldSet.addText("Charge Segment : ");
formPanel.add(fieldSet);
return formPanel;
}

private RpcProxy getProxy() {
RpcProxy proxy = new RpcProxy() {
@Override
public void load(Object loadConfig, AsyncCallback callback) {
try {
service.getVolumeRates((PagingLoadConfig) loadConfig, callback);
} catch (Exception e) {
System.out.println("Inside load method:" + e);
}
}
};

return proxy;
}

final AsyncCallback callback = new AsyncCallback() {
public void onSuccess(Object result) {
toolBar.refresh();
MessageBox.info("Success", "Record Successfully updated ", null);
}
private Widget createFailedLoginPage() {
return null;
}
public void onFailure(Throwable caught) {

}
};

private RpcProxy getRpcProxy(final String ratecode, final String startdate) {
RpcProxy rpcProxy = new RpcProxy(){
@Override
public void load(Object loadConfig, AsyncCallback callback){
try{
System.out.println(ratecode+"*******************"+startdate);
service.getChrgSeg((ListLoadConfig)loadConfig,ratecode,startdate,
new AsyncCallback(){
public void onSuccess(Object result){
System.out.println("ON SUCCESS ====>"+ result);
System.out.println("ON SUCCESS ====>"+ (result instanceof BaseListLoadResult));
BaseListLoadResult baseListLoadResult = (BaseListLoadResult)result;
List<ChargeSegment> list = baseListLoadResult.getData();
Iterator<ChargeSegment> iterator = list.iterator();
while (iterator.hasNext()) {
ChargeSegment wg = iterator.next();
System.out.println("ProviderName :: "+ wg.getSegmentName());
}
reLoadChrgSegCombo(list);
}

public void onFailure(Throwable caught){

}
});

}catch(Exception e){
System.out.println("Inside load method:" + e);
}
}
};
return rpcProxy;
}

private void reLoadChrgSegCombo(List<ChargeSegment> workGroupsList) {
listStore.removeAll();
listStore.add(workGroupsList);
comboBox.setStore(listStore);
}

private RpcProxy getChrgProxy(final String ratecode, final String startdate) {
RpcProxy proxy = new RpcProxy(){
@Override
public void load(final Object loadConfig, AsyncCallback callback){
try{
System.out.println(ratecode+"*******************"+startdate);
service.getchargesegment((ListLoadConfig)loadConfig,ratecode,startdate,
new AsyncCallback(){
public void onSuccess(Object result){
System.out.println("ON SUCCESS ====>"+ result);
System.out.println("ON SUCCESS ====>"+ (result instanceof BaseListLoadResult));
BaseListLoadResult baseListLoadResult = (BaseListLoadResult)result;
list = baseListLoadResult.getData();
Iterator<ChargeSegment> iterator = list.iterator();
while (iterator.hasNext()) {
ChargeSegment wg = iterator.next();
System.out.println("ProviderName :: "+ wg.getSegmentName()+"*****"+wg);
}
}

public void onFailure(Throwable caught){

}
});

service.getVolRateDetail((ListLoadConfig)loadConfig,ratecode,
new AsyncCallback(){
public void onSuccess(Object result){
System.out.println("ON SUCCESS ====>"+ result);
System.out.println("ON SUCCESS ====>"+ (result instanceof BaseListLoadResult));
BaseListLoadResult baseListLoadResult = (BaseListLoadResult)result;
list2 = baseListLoadResult.getData();
Iterator<VolumeRateDetail> iterator = list2.iterator();
while (iterator.hasNext()) {
VolumeRateDetail wg = iterator.next();
int segmentId = wg.getSegmentId();
//ChargeSegment chargeSegment = list.get(segmentId);
System.out.println(list.get(segmentId)+"^^^^^^^^^^^*******");
System.out.println("ProviderName :: "+ wg.getSegmentId());
}
System.out.println(list.size()+"!!!!!!!!!!!"+list2.size());
}

public void onFailure(Throwable caught){

}
});


}catch(Exception e){
System.out.println("Inside load method:" + e);
}
}
};
return proxy;
}

}

eugenparaschiv
7 May 2009, 11:18 PM
Ok, there is a post on how to structure a simple example somewhere on this forum, but some basic tips are:
- provide an EntryPoint to test, so that I can simply paste it and run it
- don't have dependencies to other classes in your project (that you don't provide) - obviously I can't run it if I don't have all the classes
- remove everything that is not relevant to the bug - clean it up to a more manageable form, so that I can see the bug and not irrelevant visual logic
There is little chance someone will actually start to parse you code like this and give you an answer.
Cheers.
Eugen.

mcosta
7 May 2009, 11:24 PM
Try with:



private void reLoadChrgSegCombo(List<ChargeSegment> workGroupsList) {
listStore.removeAll();
// listStore.add(workGroupsList); // <== Fail
listStore.addAll(workGroupsList); // <== OK
comboBox.setStore(listStore);
}
You want to add *all items in list* not the list itself.

PD: Remember there is a code format. So I do not have to copy+paste into eclipse to understand your code.

Suma
8 May 2009, 2:22 AM
List<ChargeSegment> list = new ArrayList<ChargeSegment>();
List<VolumeRateDetail> list2 = new ArrayList<VolumeRateDetail>();

final Grid grid = createVolumeRateGrid();

grid.getSelectionModel().addListener(Events.SelectionChange,new Listener<SelectionEvent>() {
public void handleEvent(SelectionEvent be) {

VolumeRate volumeRate = (VolumeRate)(be.selection.get(0));
String rateCode = volumeRate.get("volRateCode");
String startdate = volumeRate.get("start");
RpcProxy proxy = getChrgProxy(rateCode,startdate);
BaseListLoader loader = new BaseListLoader(proxy);
loader.load();

//Here i want to access the data stored in list and list2

}
});


//Method to get the data from database to two Lists

private RpcProxy getChrgProxy(final String ratecode, final String startdate) {
RpcProxy proxy = new RpcProxy(){
@Override
public void load(final Object loadConfig, AsyncCallback callback){
try{
service.getchargesegment((ListLoadConfig)loadConfig,ratecode,startdate,
new AsyncCallback(){
public void onSuccess(Object result){
BaseListLoadResult baseListLoadResult = (BaseListLoadResult)result;
list = baseListLoadResult.getData();
}
public void onFailure(Throwable caught){
}
});

service.getVolRateDetail((ListLoadConfig)loadConfig,ratecode,
new AsyncCallback(){
public void onSuccess(Object result){
BaseListLoadResult baseListLoadResult = (BaseListLoadResult)result;
list2 = baseListLoadResult.getData();
}
public void onFailure(Throwable caught){
}
});
}catch(Exception e){
System.out.println("Inside load method:" + e);
}
}
};
return proxy;
}

mcosta
8 May 2009, 3:21 AM
OK. I got the problem. You must think async. At first is hard, later it gets automatic. When you want to access list2 it is of course empty, you just initialized it to a new list!. the load lauchs the load but the callbacks is executed late, *async*. Even you do not know which one is going to be executed first. You need another callback and some kind of sync method. There is no other way. Browser javascript is single-thread. For example:




private void dataReady() {
// Do your stuff here
}

private RpcProxy getChrgProxy(final String ratecode, final String startdate) {
RpcProxy proxy = new RpcProxy() {
int pending = 2 // watch for this
@Override
public void load(final Object loadConfig, AsyncCallback callback) {
try {
service.getchargesegment((ListLoadConfig) loadConfig, ratecode, startdate, new AsyncCallback() {
public void onSuccess(Object result) {
[...]
list = baseListLoadResult.getData();
[...]
pending--;
if (pending == 0) dataReady();
}

public void onFailure(Throwable caught) {

}
});

service.getVolRateDetail((ListLoadConfig) loadConfig, ratecode, new AsyncCallback() {
public void onSuccess(Object result) {
[...]
list2 = baseListLoadResult.getData();
[...]
pending--;
if (pending == 0) dataReady();
}

public void onFailure(Throwable caught) {

}
});

} catch (Exception e) {
System.out.println("Inside load method:" + e);
}
}
};
return proxy;
}
PD: please, use the code format

anmbr
28 Sep 2011, 6:14 AM
Hi, I'm a brazilian, and I with the same problem, but I can't understand your solution for this. Would be onSuccess inside onSuccess ? I get data from database in onSuccess and stored in array, but outside onSuccess array is empty, with null elements, because assync, but how i can "wait" complete array to use out of onSuccess??

Thanks.

Sorry for my bad english

Colin Alworth
28 Sep 2011, 11:32 AM
Until onSuccess is called, there is no value - and it will almost certainly be called much after your block of code has finished running. Sometimes it is appropriate to have a rpc call inside of another onSuccess.

Take a look at http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/faca1575f306ba0f/3be719c021aa19bd to try to understand how to think in async.

anmbr
29 Sep 2011, 2:09 PM
Hi, thanks for you help, look if I understand:

I can't get the "string" return in onSuccess, I need to put this in a function outside onSuccess, and inside the function manipulate in my mode?

I'll try, and if I yet can't do that, I'll return..

let's see !

thanks

anmbr
29 Sep 2011, 3:06 PM
Not yet! OMG !

I send in attch my code.
And after I call the method "construtor" in my principal class of GWT, I have null object then. =/
I don't understand






public class PontoClass {
private String [] aux = new String [12];
protected String [] ids = new String [2];
protected Teste retorno = new Teste();


public PontoClass(){}

public Teste construtor(final String id_local){


final ConexaoAsync conexao = GWT.create(Conexao.class);

conexao.conectar(
new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
Window.alert("Erro ao conectar ao banco!");
}


public void onSuccess(String result) {

}
});



conexao.select("SELECT idlocais,nome " +
"FROM monografia.locais" +
" WHERE idlocais = "+id_local, new AsyncCallback<ArrayList<String>>() {
public void onFailure(Throwable caught) {
Window.alert("Erro no select! "+caught);
}


@Override
public void onSuccess(ArrayList<String> result) {

for(int i = 0; i < result.size(); i++){
//System.out.println(result.get(i).toString());
aux = result.get(i).toString().split("####");
ids[0] = aux[0];
ids[1] = aux[1];
montar_objeto();
}


}
});

System.out.println("idddddddd= "+retorno.id); // ALWAYS IS NULL
System.out.println("vetor id = "+ids[1]); // ALWAYS IS NULL
return retorno;
}


public void montar_objeto(){
retorno.id = ids[0];
retorno.nome = ids[1];
}
}


class Teste{
public String id;
public String nome;
public String descricao;
public String tags;
public String contato;
public int tipo;
public String geo;
public int curtiu;
public int nao_curtiu;
public int ativo;
public String data_in;
public String data_out;
}

Colin Alworth
29 Sep 2011, 3:10 PM
Here is a way that might help. Without async, your code might look like this

//start function A
//make call to server, and have return value
//deal with return value
//end function A

Making things async generally looks more like this:

//start function A
//make call to server, with callback to function B
//end function A
//start function B
//deal with return value
//end function B

Colin Alworth
29 Sep 2011, 3:47 PM
As in my last message, try moving the code that needs the string response into the onSuccess method, or, as many people prefer, into a new method.

In your example, instead of the sys.out.println calls at the end of montar_objeto(). I see you are trying to return the value afterward - that is difficult to factor out into another method. Instead, I think you need to look at how to solve your problem in another way, instead of asking the method to return a value, think more in terms of having told the server to call the _client_ when it is ready with that value. This can make some other problems more difficult to solve, but in the end it usually makes for more flexible code, and better browser performance.

Did you get a chance to go through that link?

Colin Alworth
29 Sep 2011, 3:52 PM
Here is something that may help you to understand why you are never getting the value you expect to be returned. Add a break point in montar_objeto or in the onSuccess method, and add a breakpoint at the end of the construtor method - you will find that you hit the end of construtor before onSuccess is called, because the server is still working on it. It is _not possible_ to wait until the browser has finished, at least in GWT - in other ajax frameworks, you can, but it will cause the entire browser to hang, indefinitely if something happens to the server. Not good, and GWT is written to prevent this from happening.

anmbr
29 Sep 2011, 3:53 PM
Now it's work !!
In montar_objeto I get the "map" and addOverlay, but my idea was mount a object Test or PontoClass with the info i got in return of select, and in my main class I'll work and set in map these points!
But I see add now in montar_object are more easy, I'll think about this.