Search code examples
javareactive-programmingrx-java

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?


Solution

  • 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())