[Edit2] the question changed so I adapt my answer + actually give a correct answer
I don't see other way of doing this than with a status flag:
AtomicBoolean progress = new AtomicBoolean();
observableOne
.filter(event -> !progress.get())
.flatMap(event ->
observableTwo
.doOnSubscribe(() -> progress.set(true))
.doOnTerminate(() -> progress.set(false))
)
.subscribe();
If an error happens your subscription will be canceled and you will not receive any more event, even if the button is clicked again.
If this is not what you want you can:
resubscribe on the error callback
private void bindRemoteCalls() {
if (mySubscription != null) mySubscription.unsubscribe();
AtomicBoolean progress = new AtomicBoolean();
mySubscription = observableOne
.filter(event -> !progress.get())
.flatMap(event ->
observableTwo
.doOnSubscribe(() -> progress.set(true))
.doOnTerminate(() -> progress.set(false))
)
.flatMap(event -> observableTwo, 1)
.subscribe(
data -> handleResponse(data),
error -> {
handleError(error);
bindRemoteCalls();
}
);
}
use onErrorReturn()
(combine with a doOnError()
to actually do something about it)
AtomicBoolean progress = new AtomicBoolean();
observableOne
.filter(event -> !progress.get())
.flatMap(event ->
observableTwo
.doOnSubscribe(() -> progress.set(true))
.doOnTerminate(() -> progress.set(false))
.doOnError(error -> handleError(error))
.onErrorReturn(null)
.filter(data -> data != null)
)
.subscribe(data -> handleResponse(data));
Remember using subscribeOn()
/ observeOn()
with the right schedulers if you need to.
Please consider using switchMap()
in place of flatMap()
--> if the button is pressed again the previous call is canceled (unsubscribed) and then a new one is started. Or to say it in Rx terms: the observableTwo previous subscription is unsubscribed and a new subscription is formed.
if you disable your button on unsubscribe and enable it on termination you can easily obtain the same result by making the button unclickable.