androidrx-java2mvprx-binding

How to switchMap after press button RxJava2


I study switchMap. The case is: 1) User press button 1 2) View calls Presenter method getRecord (id), and send button id. 3) Presenter subsribe on observable and emit data 4) User press button 2 5) Presenter unSubscribe of current subscriprion and create new.

I know that i have to use switchMap operator. I want to see in log this: Obs1: 0, Obs1: 1, Obs1: 2(click) Obs2: 0, Obs2: 1 .... Here is my code View:

    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    mPresenter = new Presenter();
    Button button1 = findViewById(R.id.btn_1);
    Button button2 = findViewById(R.id.btn_2);


    button1.setOnClickListener(v -> {
        mPresenter.getRecord(1);
    });

    button2.setOnClickListener(v -> {
        mPresenter.getRecord(2);
    });

Presenter:

public class Presenter {
    private final String TAG = this.getClass().getSimpleName();

    int ID = 0;
    Observable observable = Observable.just(ID);

    public void getRecord(int id) {
        observable
                .doOnNext(data -> Log.d(TAG, String.valueOf(data)))
                .switchMap(s -> getObservable(id))
                .subscribe(data -> Log.d(TAG, (String) data));
    }

    Observable<String> getObservable(int id) {
        return Observable.interval(1, TimeUnit.SECONDS)
                .map(data -> "Obs" + String.valueOf(id) + ":" + data);
    }
}


Here is my LOG:
    D/Presenter: 0
    D/Presenter: Obs1:0
    D/Presenter: Obs1:1
    D/Presenter: Obs1:2
    D/Presenter: Obs1:3
    D/Presenter: Obs1:4
    D/Presenter: Obs1:5
    D/Presenter: 0
    D/Presenter: Obs1:6
                 Obs2:0
    D/Presenter: Obs1:7
    D/Presenter: Obs2:1
    D/Presenter: Obs1:8
    D/Presenter: Obs2:2
    D/Presenter: Obs1:9
    D/Presenter: Obs2:3
    D/Presenter: Obs1:10
    D/Presenter: Obs2:4

Solution

  • I suggest having button clicks as stream of some UiEvent, merge both button streams in presenter and switchMap will work as intended.

    Pseudo code

    Observable<UiEvent> getButton1ClickEvents(){
        return RxView.clicks(button1)
              .map(new Button1ClickEvent());
    }
    Observable<UiEvent> getButton2ClickEvents(){
        return RxView.clicks(button2)
              .map(new Button2ClickEvent());
    }
    
    void getRecord(){
        Observable.merge(getButton1ClickEvents(),getButton2ClickEvents())
            .switchMap(event -> getObservable(id))
            ....
    }