Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

RxJava- CombineLatest but only fire for one Observable's emission?

Let's say I have two infinite Observables that can emit values at any moment. They combine to create a Observable<ProcessFileEvent>.

Observable<Integer>  selectedFileId= ...
Observable<MouseClick> buttonClick = ...

Observable<ProcessFileEvent> `processFileEvent` = Observable.combineLatest(selectedFileId, buttonClick, (s,b) -> {
    //create ProcessFileEvent here
});

The problem is I only want the processFileEvent to emit when buttonClick emits something, not selectedFileId. It's definitely not the behavior a user expects when a file ID is inputted and it kicks off a ProcessFileEvent. How do I combine but only emit when the buttonClick emits?

like image 746
tmn Avatar asked Jul 08 '15 19:07

tmn


2 Answers

Use withLatestFrom:

Observable<Integer>  selectedFileId= ...
Observable<MouseClick> buttonClick = ...

Observable<ProcessFileEvent> processFileEvent = buttonClick.withLatestFrom(selectedFieldId, (b,s) -> {
    //create ProcessFileEvent here
});

It only emits with when the first Observable buttonClick emits.

like image 95
paulpdaniels Avatar answered Oct 08 '22 13:10

paulpdaniels


Use .distinctUntilChanged() on the MouseClick object. That way you'll only get events when the MouseClick changes.

Create a class that contains both fileId and mouseClick:

static class FileMouseClick {
    final int fileId;
    final MouseClick mouseClick;

    FileMouseClick(int fileId, MouseClick mouseClick) {
        this.fileId = fileId;
        this.mouseClick = mouseClick;
    }
}

Then

Observable.combineLatest(selectedFileId, buttonClick, 
                         (s,b) -> new FileMouseClick(s,b))
    .distinctUntilChanged(f -> f.mouseClick)
    .map(toProcessFileEvent())
like image 28
Dave Moten Avatar answered Oct 08 '22 14:10

Dave Moten