Will an gwt rpc call ALWAYS callback to either my onsuccess or onfail methods? - gwt

I have implemented the suggestion in this post and disable my button after the the first click. How to prevent DoubleSubmit in a GWT application?
What i want to know is with my button reenabled in both my fail and success methods will it always get reenabled. Also is there any place i can put some code that i always want executed when the server replies as opposed to duplicating it in both fail and success methods

I do think that either onSuccess() or onFailure() will be called every time.
As for having a place where you can put code that will always run when getting a response to the server you could just create an AsyncCallback which has the code in it's onFailure() and onSuccess() methods. Then you can just extend that AsyncCallback everytime you create an AsyncCallback.
public MyAsyncCallback<T> extends AsyncCallback<T>(){
#Override
public void onFailure(Throwable caught){
//Do something
onResponse()
failed(caught);
}
#Override
public void onSuccess(T result){
//Do something
onResponse()
succeeded(result);
}
public void onResponse(){
// Do something or nothing by default
}
public abstract void failed(Throwable caught);
public abstract void succeeded(T result);
};
Whenever you want to create an AsyncCallback just use MyAsyncCallback:
AsyncCallback callback = new MyAsyncCallback(){
#Override
public void failed(Throwable caught){
//Do something
}
#Override
public void succeeded(T result){
//Do something
}
// Optionally override onResponse() if needed
#Override
public void onResponse(){
//Do something
}
}

Related

Unsubscribing from RxJava2/RxAndroid PublishSubject

I'm trying to replace EventBus with RxAndroid.
I want pageable fragments to subscribe/unsubscribe to an event source, these fragments get created and discarded relatively quickly, depending on how fast the user slides to a new page.
In EventBus I was able to add an decorated callback method (ie #Subscribe(threadMode = ThreadMode.MAIN)) and register/unregister in the onStart/onStop methods of the fragment.
With RxJava2 I now create a PublishSubject object in a class
public static PublishSubject<List<Long>> m_psUpdatedDays = PublishSubject.create();
public static void publishUpdatedDays(List<Long> lDay) {
m_psUpdatedDays.onNext(lDay);
}
and subscribe to this publisher in another class by calling the following in the Fragment's onStart method:
m_psUpdatedDays.observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<List<Long>>() {
#Override public void onSubscribe(Disposable d) {}
#Override public void onNext(List<Long> longs) {
...
Update Fragment UI here
...
}
#Override public void onError(Throwable e) {}
#Override public void onComplete() {}
});
My question is how can I unsubscribe this new Observer when the Fragment's onStop method is called by the system?
Do I need to store the Disposable object which I get in the onSubscribe and then call .dispose() on it in the onStop method?
You can make use of a CompositeDisposable object, which can keep a list of disposables and all of them can be disposed together.
Create a CompositeDisposable instance in the base fragment level, keep on adding your disposables into it.
public abstract class BaseFragment extends Fragment {
protected CompositeDisposable mCompositeDisposable = new CompositeDisposable();
#Override
public void onPause() {
super.onPause();
mCompositeDisposable.clear();
//clear will clear all, but can accept new disposable.
// You can call it on `onPause` or `orDestroyView` events.
}
#Override
public void onDestroy() {
super.onDestroy();
mCompositeDisposable.dispose();
//dispose will clear all and set isDisposed = true, so it will not accept any new disposable
}
}
In your fragments, subscribe to the Observable using the subscribeWith method, which gives you a disposable instantly and this disposable you can dispose later in the onPause or onDestroy events (wherever you want)
public class MyFragment extends BaseFragment {
#Override
public void onStart() {
super.onStart();
Disposable disposable = m_psUpdatedDays.observeOn(AndroidSchedulers.mainThread())
.subscribeWith(new DisposableObserver<List<Long>>() { // Use `subscribeWith` instead of `subscribe`, which will give you back the disposable , which can be disposed later
#Override
public void onNext(List<Long> longs) {
// Update Fragment UI here
}
#Override
public void onError(Throwable e) {
}
#Override
public void onComplete() {
}
});
mCompositeDisposable.add(disposable); // add the disposable to the disposable list
}
}

Whats the best way to invoke a method by Reflection in GWT

What’s the best way to invoke a method by reflection using GWT, I know that there are some frameworks like "GWT Reflection" but I really want to hear some feedback about this.
How is the best way to convert something like this:
GreetingServiceAsync service = GWT.create(GreetingService.class);
AsyncCallback callBack = new AsyncCallback< Void>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(Void result) {
}
};
service.doSomething(callBack);
in:
GreetingServiceAsync greetingService = GWT.create(GreetingService.class);
String methodName = “doSomething”;
Object service;
AsyncCallback callBack = new AsyncCallback< Void>() {
#Override
public void onFailure(Throwable caught) {
}
#Override
public void onSuccess(Void result) {
}
};
/*somehow invoke by reflection*/
Class<?> c = Class.forName(GreetingServiceAsync.class.getName());
Method method = c.getMethod(methodName, AsyncCallback.class);
method.invoke (service, callBack);
Many thanks,
Luis.
Javascript 101 - there is no concept of reflection. GWT java translates to javascript. So gwt does not provide reflection support. Every other library that states gwt reflection in their homepage are just addressing a corner functionality and mis-stating their feature.

GWT testing with mockito

Simple Question:
Verification (1) passes.
Verification (2) does not. Why? How to fix it?
Test
#Test
public void test() {
System.out.println("test");
EventBus eb = mock(EventBus.class);
MyWidget.View v = mock(MyWidget.View.class);
GreetingServiceAsync s = mock(GreetingServiceAsync.class);
HasClickHandlers button = mock(HasClickHandlers.class);
when(v.getButton()).thenReturn(button);
new MyWidget(eb, v, s);
button.fireEvent(mock(ClickEvent.class));
verify(button).addClickHandler(any(ClickHandler.class)); (1)
verify(v).alert(anyString()); (2)
}
Widget
#Inject
public MyWidget(EventBus eventBus, View view, GreetingServiceAsync service){
this.view = view;
this.service = service;
bindView();
bindEventBus();
}
private void bindView(){
view.getButton().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
view.alert("test");
}
});
}
because button is a mock, so calling fireEvent on it doesn't actually fire the event; and onClick is never called on the view.
Because Button was mocked out and there is no implementation telling it what to do when fireEvent is called. See the line:
HasClickHandlers button = mock(HasClickHandlers.class);
...
button.fireEvent(mock(ClickEvent.class));
As David Wallace said, you are mocking the button. It does lose all its abilities.
you could fix this by making a ArgumentCatptor
ArgumentCaptor<ClickHandler> captor = ArgumentCaptor.forClass(ClickHandler.class);
Then manually fire the function of the event by using:
captor.getValue().onClick(null);
This will fake the call that should have been made by the button.
If your class only has one button or one catcher for a specific event you can make it extend the ClickHandler class. Then you can just call the onClick of your class.
That is what I did:
public class ClickableElement implements HasClickHandlers{
ClickHandler ch;
#Override
public void fireEvent(GwtEvent<?> event) {
ch.onClick((ClickEvent) event);
}
#Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
this.ch = handler;
return null;
}
};

GWT RPC mechanism how to use non void return type

I have a scenario wherein I need to specify a return type to the Synchrnous function, the code is as follows :
#RemoteServiceRelativePath("show_box")
public interface ShowBoxCommandService extends RemoteService{
public ArrayList<String> showBox();
}
The implementation of the method on the server is :
public ArrayList<String> showBox() {
ArrayList<String> box = new ArrayList<String>();
Iterator<Box> boxes = BoxRegistry.getInstance().getBoxes();
while (boxes.hasNext()) {
box.add(boxes.next().toString());
}
return box;
}
I am trying to define the callback variable in the following format at the client side in order to call the method
AsyncCallback<Void> callback = new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
// TODO: Do something with errors.
// console was not started properly
}
#Override
public void onSuccess(Void result) {
// TODO Auto-generated method stub
// dialog saying that the console is started succesfully
}
};
update with the aync interface code :
public interface ShowBoxCommandServiceAsync {
void showBox(AsyncCallback<ArrayList<String>> callback);
}
But this is causing the definition of the method in the Async method to change.
Any ideas or clues will be helpful.
Thanks,
Bhavya
P.S. Apologies if this is a repetition
The callback should be:
AsyncCallback<ArrayList<String>> callback = new AsyncCallback<ArrayList<String>>() {
public void onFailure(Throwable caught) {
// TODO: Do something with errors.
// console was not started properly
}
#Override
public void onSuccess(ArrayList<String> result) {
// TODO Auto-generated method stub
// dialog saying that the console is started succesfully
}
};
If you don't need to utilize the result then you can ignore it, but if that is the case, you should probably question your design and why you would need the method to return an ArrayList<String> in the first place.
If the service interface looks like this:
public interface ShowBoxCommandService extends RemoteService {
public ArrayList<String> showBox();
}
then you must have an associated async interface:
public interface ShowBoxCommandServiceAsync {
public void showBox(AsyncCallback<ArrayList<String>> callback);
}
Which means, that the type of the callback that you should pass to showBox is AsyncCallback<ArrayList<String>>.
new AsyncCallback<ArrayList<String>>() {
#Override
public void onSuccess(ArrayList<String> list) {
// ...
}
#Override
public void onFailure(Throwable caught) {
// ...
}
}
Your callback should not be Void. If your synchronous method returns a List of Strings, the async callback method should receive the List. You'll have to use the ArrayList, because the class needs to implement the Serializable interface.
AsyncCallback<ArrayList<String>> callback = new AsyncCallback<ArrayList<String>>() {
public void onFailure(Throwable caught) {
// TODO: Do something with errors.
// console was not started properly
}
#Override
public void onSuccess(ArrayList<String> result) {
// TODO Auto-generated method stub
// dialog saying that the console is started succesfully
}
};
Huh? Your method returns an ArrayList and you are declaring void in your call?
Change <Void> to <ArrayList<String>>

Default AsyncCallback in GWT

Doing my app, I got bored from always implement the same default error treatment (show a message, caught.printstacktrace and etc..) in the asynccallback onfailure.
I wonder if you can make a generic treatment or standard treatment, something like that.
Thanks.
I assume you are using standard GWT-RPC. Something like this might help
public abstract class AbstractCallBack<T> implements AsyncCallback<T>{
#Override
public void onFailure(Throwable caught) {
//Default error Handling code goes here
}
}
And whenever you use your service instead of instantiating an AsyncCallback you can instantiate this class and have generalized error handling.
SomeServiceAsync service = GWT.create(SomeService.class);
service.someMethod("Hello!", new AbstractCallBack<String>() {
#Override
public void onSuccess(String result) {
// TODO Auto-generated method stub
}
});