0

I have a label which displays error messages. If you double click on it you get a big dialog showing the whole stack trace. I have two observables: One for the errors and one for the click events:

final ConnectableObservable<Notification> errorNotifications = pm
    .getNotificationObservable()
    .filter(notification -> notification.getType().isError() && !notification.getLongMessage().isEmpty())
    .replay(1);

errorNotifications.connect();

SwingObservable.fromMouseEvents(dialog.getMessagePanel().getMessageLabel())
               .map(MouseEvent::getClickCount)
               .filter(number -> number >= 2)
               .subscribe(integer -> errorNotifications
                   .take(1)
                   .subscribe(notification -> ErrorDialog.showError(dialog.getFrame(), "Error", notification.getLongMessage())));

I filter the notification observable to only show erros and replay the last error if I subscribe from it from inside my click observable.

Now my question is, are there any operators in RxJava by which I can do this more... neatly? I tried to use combineLatest() but this had the effect, that every time an error ocured the dialog would open.

In a more abstract way: I have two observables, one is like the "master": If the master observable (click observable) emits an item, the other observable (my error notifications) should emit the latest item.

morpheus05
  • 4,772
  • 2
  • 32
  • 47

1 Answers1

2

Using another Observable in a subscription is often a design flaw.

You may check the flatMap operator in this response. It will help you to emits error notification when you emit another event.

For example, if you want to use flatMap operator with your code, it can be updated like this :

 final ConnectableObservable<Notification> errorNotifications = 
                                                  pm.getNotificationObservable()
                                                    .filter(notification -> notification.getType().isError() && !notification.getLongMessage().isEmpty())
                                                    .replay(1);

errorNotifications.connect();

SwingObservable.fromMouseEvents(dialog.getMessagePanel().getMessageLabel())
           .map(MouseEvent::getClickCount)
           .filter(number -> number >= 2)
           .flatMap(integer -> errorNotifications.take(1))
           .subscribe(notification -> ErrorDialog.showError(dialog.getFrame(), "Error", notification.getLongMessage())));
Graham
  • 7,431
  • 18
  • 59
  • 84
dwursteisen
  • 11,435
  • 2
  • 39
  • 36
  • flatMap seems to work, but I'm not sure if I understand the underlying tech: So a ReplaySubject will emit the last item on subscrption which means that flatMap() also subscribes to the resulting observable from the passed mapping function...? – morpheus05 Aug 05 '16 at 14:49
  • flatMap will merge all result from observables that your lambda return. So with a Replaysubject, you'll be notified of the last events, and the subsequent events too. With the take operator, you'll be notified, each times, only of the last events. – dwursteisen Aug 05 '16 at 14:54