GWTP : events and nested presenters - events

I have some problems with events in GWTP.
I have a MainPresenter which extends TabContainerPresenter.
This presenter is linked to a MainView which contains some ui components + some com.gwtplatform.mvp.client.Tab : HomeTab, ContactTab and so on.
MainPresenter is supposed to react to some events "MyEvent"
MyEvent has a corresponding MyHandler and has been created following those good practices http://arcbees.wordpress.com/2010/08/24/gwt-platform-event-best-practice/
When I fire an event from a ui component of MainView like this :
MyEvent.fire(this, new MyEventContext(..));
I correctly catch the event in MainPresenter.
But When I do exactly the same in one of the "Tab Presenter", the event is not caught by the MainPresenter.
For example, in HomePresenter which is the "HomeTab" of MainPresenter, when I do
MyEvent.fire(this, new MyEventContext(..));
I can catch the event from the HomePresenter but not from the MainPresenter.
Any idea?

Make sure you respect those rules:
The EventBus you inject in your View is com.google.web.bindery.event.shared.EventBus (and not com.google.gwt.event.shared.EventBus)
In the Presenter that handles the event (HomePresenter or MainPresenter), register to the event using the addRegisteredHandler method, inside the onBind lifecyle method:
#Override
protected void onBind() {
super.onBind();
addRegisteredHandler(MyEvent.getType(), this);
}
I don't know what is your particular mistake that you've done. To help you, I made a quick proof of concept which shows that events can be sent from a tabbed presenter to a TabContainerPresenter. Clone this project, and head to the #!settingsPage. You'll see two "Fire true" and "Fire false" buttons, which will fire events that will be caught by the ApplicationPresenter.

First, let me thank you for this awesome POC, it is an excellent basis to understand what was going wrong. I saw that I actually did not use GWTP in the good way.
The root problem was that I had 2 differents eventBus
I saw it by trying
Log.info("eventBus: "+eventBus)
in the MainPresenter and in the HomePresenter. The logs showed that they did not have the same hashcode.
This was due to the fact that sometimes, I accessed directly the EventBus by doing:
EventBus.Util.getInstance();
Whereas the placeManager instantiated with:
DelayedBindRegistry.bind(GWT.create(MyInjector.class))

Related

Why doesn't my Android ViewModel's Room RxJava3 Flowable publish any result when my Activity is paused?

I'm aware it's a complex question that cannot have a definite answer without posting a few hundreds of lines of code, which is why I'm looking for help through general ideas and pointers.
I have a Room #Query returning a RxJava3 Flowable<List<...>> which I subscribe to on RxJava thread Schedulers.io(), and observe from an activity-scoped ViewModel on RxJava thread AndroidSchedulers.mainThread(). The data is then stored in my ViewModel as LiveData, which plays better than RxJava when it comes to handle Android components' lifecycle.
The idea is to have a clean and immediate data update pattern, not to have to handle disposal and re-subscription separately on each activity or fragment lifecycle event such as onPaused and onResumed, and being updated in the background even when my activity is hidden in order to avoid that awful refresh lag when returning to my activity. I was pretty amazed at that design pattern. I still am, but I'm beginning to have doubts.
When starting another activity with the same design pattern, I do change a value and immediately get an updated List<...> from the other ViewModel. Different Activity, different ViewModel, same design, same database table. When returning to the first Activity, I find that the new data does never get updated: Room did not emit any update even though the data set has changed. I have to dispose and subscribe again in order to see the new data.
So my question is: any pointer on where the source of my problem might be?! Is there something rotten in the core of this design pattern? Something I misunderstood about all those things are supposed to work together? Is it just a mistake of mine due to some threading issue? Or should I fill a bug report for Room?
I tried to observe another non-Room RxJava3 observable from the ViewModel of my first Activity, and it does get updates when its data set is updated.
By the way, I also use Hilt in order to inject eveything as #Singleton.
Thank you for your time :-)
After a week of headaches, I have finally stumbled upon a solution, which happens to be clean and elegant.
The issue was RxJava, which, I just learnt, is not supposed to seamlessly handle multiple subscriptions to the same Observable. The solution is supposedly to make use of the publish(), connect(), refcount() operators, or better use the shortcut share(). I tried every way I could think of, without success (it actually made it worse). I also tried to subscribe() to the Room Flowable from my repository and proxy it through a BehaviorSubject.
There was this weird org.reactivestreams.Publisher in Room's documentation, whose added value I wouldn't know, and whose origin wasn't even my familiar io.reactivex.rxjava3. It turns out it that was the solution. Edit: It turns out Publisher is an interface that Flowable happens to implement.
build.gradle
implementation 'android.arch.lifecycle:reactivestreams:+'
Dao.java
#Query("...")
Flowable<List<...>> getFlowable();
ViewModel.java
public liveData;
#Inject
public ViewModel(#NonNull RoomDatabase roomDatabase) {
liveData = LiveDataReactiveStreams.fromPublisher(roomDatabase.dao().getFlowable());
}
It seems too easy to be true, but as far as I can see it seems to work perfectly better this way.
Edit:
It turns out the root of this issue was a slight little bit more vicious than I thought. I assumed #InstallIn(SingletonComponent.class) in my dependency injection #Module was enough, but apparently a #Singleton annotation on each #Provides method is also required.
#Module
#InstallIn(SingletonComponent.class)
public abstract class DependencyInjection
{
#Provides
#NonNull
#Singleton // do not omit this
public static DataDao provideDataDao(#NonNull RoomDatabase roomDatabase) {
return roomDatabase.dataDao();
}
#Provides
#NonNull
#Singleton // do not omit this
public static RoomDatabase provideRoomDatabase(#ApplicationContext Context applicationContext) {
return
BuildConfig.DEBUG ?
Room.databaseBuilder(applicationContext, RoomDatabase.class, "playground.db").fallbackToDestructiveMigration().build() :
Room.databaseBuilder(applicationContext, RoomDatabase.class, "playground.db").build() ;
}
}

Laravel - can I bind an event to a notification?

First, I'll describe the context.
I have a lot of notifications that refering to changes in the Offer, for example: offerEditedBySeller, offerEditedByAdmin, offerTurnOff, etc. They are triggered in many places in controllers.
Now I'm implementing an expanded cache and I want to make the event OfferChange in which the cache for specific offer will be reloaded. First, I wanted to trigger these notifications in events, but I realized that to make it work, I'll have to duplicate every notification.
For example, let's assume I have the event( new OfferEdited() ). Its listeners will be RefreshCacheForOffer, SendNotificationsAboutOfferEdit etc. For every notification like offerEdited I need to create listener SendNotificationsAboutOfferEdit, which just trigger specific Notification. I think it's not what I want to reach.
Is there a way to bind events/listeners with a notification? No matter if it would be offerEdited, offerApproved or offerDisapproved it would be bind with the event OfferChange, which would trigger the listener RefreshCacheForOffer and the specific job next. This way I wouldn't have to change the code in every controller's action and create a lot of unnecessary events and listeners. Is it possible?
Edit:
I know I can just do:
$user->notify(new offerEdited($offer));
event( new OfferChange($offer) );
But I hope there is a way to better organize it.
To avoid changing lots of code in your controllers you could model it inside your Model and pick up on the 'created' or 'updated' events of the model, and then call subsequent events.
class Offer extends Model
{
protected static function booted()
{
static::updated(function ($user) {
// check for condition and trigger event such as OfferEditedBySeller
});
}
}
If you want to use event/listener architecture then I think one event and listener for ever notification is the way you have to go.
Alternatively, don't bother with events/listeners - just send your notifications from the controller or from the 'created' or 'updated' events of the model. Cut out the middleman (events/listeners) and you'll have more explicit code which is easier to follow.
Events/listeners are good when you need to decouple and abstract - but if you are doing explicit things then not using them might be simpler for you.

Xamarin Async Constructor

For my application I need to fetch some data asynchronously and do some initialization for each page. Unfortunately, a constructor does not allow me to make asynchronous calls. I followed this article and put all of my code into the OnAppearing method. However, since then I ran into multiple issues since each platform handles the event a little bit differently. For example, I have pages where you can take pictures, on iOS the OnAppearing is called again every time after the camera is closed while Android doesn't. It doesn't seem like a reliable method for my needs, which is also described here:
Calls to the OnDisappearing and OnAppearing overrides cannot be treated as guaranteed indications of page navigation. For example, on iOS, the OnDisappearing override is called on the active page when the application terminates.
I am searching for a method/way where I can perform my own initialization. The constructor would be perfect for that but I cannot perform anything asynchronously in there. Please do not provide me with any work arounds, I am searching for a solution that is the "recommended" way or maybe someone with a lot of experience can tell me what they are doing. (I also don't want to .Wait() or .Result as it will lock my app)
You can use Stephen Cleary's excellent NotifyTaskCompletion class.
You can read more how it works and what to do/don't in these cases in Microsoft's excellent Async Programming : Patterns for Asynchronous MVVM Applications: Data Binding. The highlights of this topics are:
Let’s walk through the core method
NotifyTaskCompletion.WatchTaskAsync. This method takes a task
representing the asynchronous operation, and (asynchronously) waits
for it to complete. Note that the await does not use
ConfigureAwait(false); I want to return to the UI context before
raising the PropertyChanged notifications. This method violates a
common coding guideline here: It has an empty general catch clause. In
this case, though, that’s exactly what I want. I don’t want to
propagate exceptions directly back to the main UI loop; I want to
capture any exceptions and set properties so that the error handling
is done via data binding. When the task completes, the type raises
PropertyChanged notifications for all the appropriate properties.
A sample usage of it:
public class MainViewModel
{
public MainViewModel()
{
UrlByteCount = new NotifyTaskCompletion<int>(
MyStaticService.CountBytesInUrlAsync("http://www.example.com"));
}
public NotifyTaskCompletion<int> UrlByteCount { get; private set; }
}
Here, the demo is about binding the returned asynchronous value to some bindable property, but of course you can you is without any return value (for simple data loading).
This may be too simple to say, but you CAN run asynchronous tasks in the constructor. Just wrap it in an anonymous Task.
public MyConstructor() {
Task.Run(async () => {
<Your code>
}
}
Be careful when doing this though as you can get into resource conflict issues if you accidentally open the page twice.
Another thing I like to do is use an _isInit flag, which indicates a first time use, and then never again.

Laravel: Call function on sync or attach

Whenever I modify a relationship (many to many) I want to do another action. As far as I know this can't be done using event listeners (see https://github.com/laravel/framework/issues/2303). This works,
function setUserGroups($ids){
$this->groups->sync($ids);
doSomethingElse();
}
The downside is that it's not intuitive for other developers to remember to use this function. Generally I'm able to attach behavior to change in other attributes using mutators, defining them as guarded or adding events, and I just want to be able to do something similar with syncing/attaching.
I don't see creating a repository as a solution for this. We're not using the repository pattern in our application and honestly I see this issue coming up there as well.
You may register your custom event handlers and listeners:
// register listener
Event::listen('user.groupsModified', 'User#onGroupsModified');
Event Handler:
// Handle event in User class
function onGroupsModified($event)
{
}
Then fire the event in setUserGroups function:
function setUserGroups($ids){
$this->groups->sync($ids);
// Fire the event
Event->fire('user.groupsModified');
}
This way, you can abstract the dependency from the setUserGroups method, now you only need to fire the event and no need to know the handler's name.

Is it a good design to put event handling code into an own method?

Image a Button on your windows form that does something when being clicked.
The click events thats raised is typically bound to a method such as
protected void Button1_Click(object
sender, EventArgs e) {
}
What I see sometimes in other peoples' code is that the implementation of the buttons' behaviour is not put into the Button1_Click method but into an own method that is called from here like so:
private DoStuff() { }
protected void Button1_Click(object
sender, EventArgs e) {
this.DoStuff();
}
Although I see the advantage here (for instance if this piece of code is needed internally somewhere else, it can be easily used), I am wondering, if this is a general good design decision?
So the question is:
Is it a generally good idea to put event handling code into an own method and if so what naming convention for those methods are proven to be best practice?
I put the event handling code into a separate method if:
The code is to be called by multiple events or from anywhere else or
The code does not actually have to do with the GUI and is more like back-end work.
Everything small and only GUI-related goes always into the handler, sometimes even if it is being called from the same event (as long as the signature is the same). So it's more like, use a separate method if it is a general action, and don't if the method is closely related to the actual event.
A good rule of thumb is to see whether the method is doing sometihng UI specific, or actually implementing a generic action. For example a buttock click method could either handle a click or submit a form. If its the former kind, its ok to leave it in the button_click handler, but the latter deserves a method of its own. All I'm saying is, keep the single responsibility principle in mind.
In this case, I'd keep the DoStuff() method but subscribe to it with:
button1.Click += delegate { DoStuff(); }
Admittedly that won't please those who do all their event wiring in the designer... but I find it simpler to inspect, personally. (I also hate the autogenerated event handler names...)
The straight answer is yes. It's best to encapsulate the task into it's own method not just for reuse elsewhere but from an OOP perspective it makes sense to do so. In this particular case clicking the button starts a process call DoStuff. The button is just triggering the process. Button1_Click is a completely separate task than DoStuff. However DoStuff is not only more descriptive, but it decouples your button from the actual work being done.
A good rule of thumb is to see whether
the method is doing sometihng UI
specific, or actually implementing a
generic action. For example a buttock
click method could either handle a
click or submit a form. If its the
former kind, its ok to leave it in the
button_click handler, but the latter
deserves a method of its own. All I'm
saying is, keep the single
responsibility principle in mind.
I put the event handling code into a
separate method if:
The code is to be called by multiple events or from anywhere else
or
The code does not actually have to do with the GUI and is more like
back-end work.
Everything small and
only
GUI-related goes always into the
handler, sometimes even if it is being
called from the same event (as long as
the signature is the same). So it's
more like, use a separate method if it
is a general action, and don't if the
method is closely related to the
actual event.

Resources