Best practice for using values returned in callbacks (RequestFactory)

39 views
Skip to first unread message

Alexander Orlov

unread,
Aug 5, 2011, 5:48:32 AM8/5/11
to google-we...@googlegroups.com
In GWT and particularly the RequestFactory framework many callbacks are used to retrieve certain values
    
void callBack(final Integer userId) {
        final MainRequestFactory.ResourceRequest reqFactory = mainRequestFactory.resourceRequest();
        final com.google.web.bindery.requestfactory.shared.Request<Integer> req = reqFactory.getUserResourceId(userId);
        req.fire(new Receiver<Integer>() {
            @Override
            public void onSuccess(final Integer response) {
               System.out.println("My VALUE I want to return or assign to globally accessible variable = " + response); // MyValue
            }
        });
    }

However I cannot neither return MyValue or assign it to a (even static) field because the callBack is asynchronous. 

What is the best (a good one is fine enough too :) practice to process MyValue?

Jens

unread,
Aug 5, 2011, 6:15:59 AM8/5/11
to google-we...@googlegroups.com
You can assign your response to an instance variable, you just can not write this.variable inside onSuccess because that references the Receiver and not the real class that contains the async call. Just omit "this" and it should work. If you want to be complete you could write it the long way "RealClass.this.variablename". I do this all the time in my async callbacks. But its only useful if you want to remember some information obtained by an async call. If you really need to process the response you have to do it in the onSuccess method either directly or by calling a separate method (or by firing an event which is basically the same as calling a separate method).

-- J.

Alexander Orlov

unread,
Aug 5, 2011, 6:43:09 AM8/5/11
to google-we...@googlegroups.com
On Fri, Aug 5, 2011 at 12:15 PM, Jens <jens.ne...@gmail.com> wrote:
You can assign your response to an instance variable, you just can not write this.variable inside onSuccess because that references the Receiver and not the real class that contains the async call. Just omit "this" and it should work.

Yep, that's basically what I've done too but I could not imagine assigning a value to a (global) field could be advisable.
 
If you want to be complete you could write it the long way "RealClass.this.variablename". I do this all the time in my async callbacks. But its only useful if you want to remember some information obtained by an async call.

That's almost always the case.
 
If you really need to process the response you have to do it in the onSuccess method either directly or by calling a separate method (or by firing an event which is basically the same as calling a separate method).

So If I have a callback that requires a value from another callback, I have to chain these callbacks? Could result in a pretty long callback chain...

-Alex 

Jens

unread,
Aug 5, 2011, 7:06:14 AM8/5/11
to google-we...@googlegroups.com
 
If you really need to process the response you have to do it in the onSuccess method either directly or by calling a separate method (or by firing an event which is basically the same as calling a separate method).

So If I have a callback that requires a value from another callback, I have to chain these callbacks? Could result in a pretty long callback chain...


Yes you have to use chaining or you introduce a new service method that does all the work in just one server request. If you have code flows like finding an ID_b for a given ID_a and then immediately use ID_b to fetch the final object you could create a specialized method that takes ID_a and directly fetches and returns the final object. Finding ID_b would then only happen on server side.
I prefer the last option as I want to reduce server requests as much as possible.

If you have to chain then you should call good named methods in your callbacks onSuccess methods to start the next server request. I think this will increase readability at least a bit.


Alexander Orlov

unread,
Aug 5, 2011, 7:34:08 AM8/5/11
to google-we...@googlegroups.com
On Friday, August 5, 2011 1:06:14 PM UTC+2, Jens wrote:
Yes you have to use chaining or you introduce a new service method that does all the work in just one server request. If you have code flows like finding an ID_b for a given ID_a and then immediately use ID_b to fetch the final object you could create a specialized method that takes ID_a and directly fetches and returns the final object. Finding ID_b would then only happen on server side.
I prefer the last option as I want to reduce server requests as much as possible.

Plausible. 

If you have to chain then you should call good named methods in your callbacks onSuccess methods to start the next server request. I think this will increase readability at least a bit.

Might increase it but I'm afraid chaining produces badly readable code by its nature. Working with methods which are independent from each other would simplify many things. OTOH you can do everything server-side which encourages to write very performant code.

Thx for the enlightenment!
Alex
Reply all
Reply to author
Forward
0 new messages