Places & Activities - best practice of asynchronous data loading

369 views
Skip to first unread message

Zdenek

unread,
Feb 7, 2012, 7:12:04 AM2/7/12
to google-we...@googlegroups.com
Hi! I have simple question about Places & Activities. I'd like to know how asynchronous calls (through RequestFactory) should be made, what's the best practice.

1) Is good to control loading from the view? I mean passing receiver from the view to the activity to be able to act on onSuccess?

public interface MyView extends IsWidget {
void setPresenter(Presenter presenter);

public interface Presenter {
void goTo(Place place);
void fetchSomeData(Receiver<List<SomeDataProxy>> receiver);
void fetchSomeDataMore(SomeDataProxy someData, Receiver<List<SomeDataMoreProxy>> receiver);
}
}

2) Or should I go without passing receiver and define two-way communication? (IMO this approach's worse than 1st one)

public interface MyView extends IsWidget {
void setPresenter(Presenter presenter);
void setSomeData(List<SomeDataProxy> someData);
void setSomeDataMore(List<SomeDataMoreProxy> someDataMore);

public interface Presenter {
void goTo(Place place);
void fetchSomeData();
void fetchSomeDataMore(SomeDataProxy someData);
}
}

3) Or I'm completelly wrong and this kind of stuff should be done differently? :-)

Thanks for your ideas, how you controll your asynchronous data loading.

Regards,
Zdenek

Thomas Broyer

unread,
Feb 7, 2012, 8:58:18 AM2/7/12
to google-we...@googlegroups.com


On Tuesday, February 7, 2012 1:12:04 PM UTC+1, Zdenek wrote:
Hi! I have simple question about Places & Activities. I'd like to know how asynchronous calls (through RequestFactory) should be made, what's the best practice.

First, your questions are about MVP, not about Places or Activities.

1) Is good to control loading from the view? I mean passing receiver from the view to the activity to be able to act on onSuccess?

public interface MyView extends IsWidget {
void setPresenter(Presenter presenter);

public interface Presenter {
void goTo(Place place);
void fetchSomeData(Receiver<List<SomeDataProxy>> receiver);
void fetchSomeDataMore(SomeDataProxy someData, Receiver<List<SomeDataMoreProxy>> receiver);
}
}

2) Or should I go without passing receiver and define two-way communication? (IMO this approach's worse than 1st one)

public interface MyView extends IsWidget {
void setPresenter(Presenter presenter);
void setSomeData(List<SomeDataProxy> someData);
void setSomeDataMore(List<SomeDataMoreProxy> someDataMore);

public interface Presenter {
void goTo(Place place);
void fetchSomeData();
void fetchSomeDataMore(SomeDataProxy someData);
}
}

Your view shouldn't "fetch" data, that's the role of the presenter. The presenter should "drive" the view, not the other way around. The view's responsibility (besides displaying things) is to route user-initiated events to the presenter so it can react to them.

Same for your goTo(Place) method: the view should tell the presenter that some link/button/whatever has been "actioned", and the presenter translates that into a Place and a call to PlaceController#goTo.

Zdeněk Doležal

unread,
Feb 7, 2012, 9:09:36 AM2/7/12
to google-we...@googlegroups.com
Thank you for your reply. I probably didn't describe my question exactly because you misunderstood it completelly.

I'm talking about GWT MVP approach through Places & Activities -  http://code.google.com/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html 

- I'm providing fully MVP friendly interfaces that looks nearly same as in that article (View implements it and activity implements its Presenter interface part).
- I'm not talking about fetching data in views anywhere in my question, only whether view can pass Receiver into Activity.

Regards,
Zdenek

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-web-toolkit/-/sNxXHwQip9gJ.

To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.



--
S pozdravem
Zdeněk Doležal

Jens

unread,
Feb 7, 2012, 10:46:25 AM2/7/12
to google-we...@googlegroups.com
whether view can pass Receiver into Activity.


In both cases (Presenter.setReceiver(..) vs. View.setReceivedProxies(..) ) you will do the actual request in the activity. 

One difference between both is, that as soon as your activity has to calculate something based on the received data this calculation would go into the view if you choose Presenter.setReceiver(..) and implement the Receiver as anonymous inner class in the view. Now you need a slow GWTTestCase to test that calculation logic which is what we want to avoid by using MVP. 
If you want to use a fast JUnit test you could implement the Receiver as a concrete class (so the receiver can be used outside a view implementation), but in that case this concrete class needs a reference to the view interface which in turn must have setter methods (e.g. View.setReceivedProxies() ). Now you haven't really won anything because the setter methods could also be called directly by the activity.

A second difference is that you dictate the used communication layer if you choose Presenter.setReceiver(..) and you use a RequestFactory Receiver. If you plan to change server communication you may also have to change your view (sure there are ways to avoid this, e.g. a general callback interface instead of the RequestFactory Receiver interface, but I guess it will make your code a bit ugly).

So as Thomas said, use setter methods on your view interface to push data to the view (or use the editor framework).

I do my stuff based on: http://code.google.com/intl/de-DE/webtoolkit/articles/mvp-architecture-2.html and it works great. In addition I dont use the term "Presenter" for the interface defined inside the view interface. I just call it "Delegate" because it simply only contains delegate methods that are called based on user input events (e.g. Delegate.createNewProxy() when the "New"-Button is clicked in the view).

-- J.

Thomas Broyer

unread,
Feb 7, 2012, 11:16:17 AM2/7/12
to google-we...@googlegroups.com


On Tuesday, February 7, 2012 3:09:36 PM UTC+1, Zdenek wrote:
Thank you for your reply. I probably didn't describe my question exactly because you misunderstood it completelly.

I'm talking about GWT MVP approach through Places & Activities -  http://code.google.com/webtoolkit/doc/latest/DevGuideMvpActivitiesAndPlaces.html 

Places and Activities, despite what can be said in the docs, have nothing to do with MVP (you can very well make an Activity that doesn't use MVP).
Whether you use Activities or not (e.g. following the "part II" tutorial) doesn't change your question.

- I'm providing fully MVP friendly interfaces that looks nearly same as in that article (View implements it and activity implements its Presenter interface part).
- I'm not talking about fetching data in views anywhere in my question, only whether view can pass Receiver into Activity.

You're defining fetchXxx methods on your presenter, to be called by the view, so the view indeed is "fetching" data (through the presenter, but that doesn't change the problem).

Zdeněk Doležal

unread,
Feb 8, 2012, 6:57:22 AM2/8/12
to google-we...@googlegroups.com
Thank you for your replies.

Thomas, it was me who misunderstood your answer ;-). So are saying that if view is calling fetchXxx it is actually "fetching" data. So, I can rename then method from fetchXxx to onDataNeeds and its fine? But back to the problem, whats best solution (just interface with methods) for following situation:

1) Presenter is starting view.
2) View is building some widgets, components etc.
3) One widget need to be fill with data of EntityProxy (so call to presenter is needed).
4) After having a response, view continues to build more widget according results.
5) For some extra widgets view has created, we need another bunch of data based on concrete EntityProxy (so call for extra data).
6) That widgets need to be filled after response from presenter is received.

Because of asynchronous communication, there must be defined "setter methods" on the view (if I don't use callbacks from the view, eg Receiver) for setting the reponses. These methods tends to be a little problematic because you probably have to find right widget the response is concerned to (this is not needed with callbacks because you have your final variables available). And this is my problem.

Am I really violating MVP design with the callbacks? Because this "finding" of widgets / elements after response is received can be time consuming.

Solution with callbacks.
interface presenter {
  onDataNeeds(Receiver callback);
  onExtraDataNeeds(EntityProxy item, Receiver callback);
}

No special methods on view. But without callbacks, there must be two setter methods, eg:
interface view {
  setData(data);
  setExtraData(EntityProxy item);
}

You need to find correct widget in setExtraData according item. You cannot pass widget information to presenter. And for example if you have table and want to modify some row, you have to go through it and find that row based on EntityProxy item.

Zdenek

--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.

To post to this group, send email to google-we...@googlegroups.com.
To unsubscribe from this group, send email to google-web-tool...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.

Thomas Broyer

unread,
Feb 9, 2012, 4:34:31 AM2/9/12
to google-we...@googlegroups.com


On Wednesday, February 8, 2012 12:57:22 PM UTC+1, Zdenek wrote:
Am I really violating MVP design with the callbacks?

I'd say yes (at least it probably makes things harder to unit-test, which is one of the reasons to use MVP int he first place).

Now the question is whether it's a real problem.

My rule of thumb: do what you think is best for you, don't try to achieve "theoretical purity" at all cost, but stay "agile" and don't fear refactoring things if/when you think you found a better solution (as in "would be better for you", not "would move me nearer to theoretical purity").

Brandon Donnelson

unread,
Feb 19, 2012, 11:48:24 PM2/19/12
to google-we...@googlegroups.com
Great points Thomas. Just an excellent way to say that rule of thumb!
Brandon
Reply all
Reply to author
Forward
0 new messages