RxBinding icon indicating copy to clipboard operation
RxBinding copied to clipboard

only one observable at a time?

Open adennie opened this issue 10 years ago • 20 comments

I'm JUST dipping my toes into RxBinding; looks very promising for my current project. Initially I'm interested in using it for some form field validation. I see a lot of comments in the code saying "Only one observable can be used for a view at a time". By that, do you mean only one observable of a particular kind, or only one observable, period? For example, I have a login screen with username and password TextViews. I'd like to observe the text values entered into the username field via RxTextView.textChanges and simultaneously observe that same field losing focus via RxView.focusChanges. This way, I can capture the username as it is being entered, and then when the user changes focus to the password field, I can validate the entered username and flag any problems (too short, invalid chars, etc.). Can I have both of these observables bound to the same TextView at the same time, or is that not going to work?

P.S. is there any discussion forum yet for RxBinding? I couldn't find anything.

adennie avatar Sep 16 '15 21:09 adennie

It's only one instance per view listener. If you do RxView.clicks twice on the same view, only the second one will actually receive events.

We can improve the wording.

JakeWharton avatar Sep 16 '15 21:09 JakeWharton

@JakeWharton Should we add warning/debug logs on these occasions?

xfumihiro avatar Sep 18 '15 14:09 xfumihiro

How would you detect it? A strict mode-like feature would be interesting, but it's not easy to consume debug versions of libraries as remote dependencies.

On Fri, Sep 18, 2015, 10:26 AM Fumihiro Xue [email protected] wrote:

@JakeWharton https://github.com/JakeWharton Should we add warning/debug logs on these occasions?

— Reply to this email directly or view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-141467410 .

JakeWharton avatar Sep 18 '15 14:09 JakeWharton

What about using bytecode injection? Just like Hugo, we could add annotations to the bindings that use "set listener methods" behind the scene and detect if it get subscribed more than once.

xfumihiro avatar Sep 19 '15 00:09 xfumihiro

Basically we just add Exclusive annotations on those and if they're subscribed more than once at a time without being unsubscribed first, show a warning message on the log. Here's a done and tested fork.

xfumihiro avatar Sep 20 '15 06:09 xfumihiro

As for strict-mode kind of solutions, I cannot think of any thing that's nice and clean. Should I just send a PR on this?

xfumihiro avatar Sep 21 '15 23:09 xfumihiro

Let me get caught up on other PRs before we take this further. I've been busy on other things and need to clean out some backlog first.

On Mon, Sep 21, 2015, 7:41 PM Fumihiro Xue [email protected] wrote:

As for strict-mode kind of solutions, I cannot think of any thing that's nice and clean. Should I just send a PR on this https://github.com/JakeWharton/RxBinding/compare/master...xfumihiro:feature/debug-aop?expand=1 ?

— Reply to this email directly or view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-142138671 .

JakeWharton avatar Sep 22 '15 01:09 JakeWharton

Why not just implement multiple listeners? :-) It would be very comfortable to use (Kotlin):

pass.focusChanges().bindToLifecycle(this).subscribe {
...
}

So it would be just like usual events but with multiple listeners support :-)

egslava avatar May 02 '16 10:05 egslava

Because 99% of the time you only need one and I don't want the overhead of multiple listener support for all those cases just to support a 1% use. You can use RxJava's built-in mechanisms for sharing observables to support multiple subscribers.

JakeWharton avatar May 02 '16 13:05 JakeWharton

I have a zero-overhead plan to fix this. Hoping to get something prototyped soon.

JakeWharton avatar Nov 05 '16 15:11 JakeWharton

Well, zero-overhead in the common (single observer) case.

JakeWharton avatar Nov 05 '16 15:11 JakeWharton

In some of cases rxBinging allows to multiple observable at a time eg. when we internally use addListener instead setListener. Maybe we should mention it in javaDoc or create annotation for it.

marcinsus avatar Dec 09 '16 17:12 marcinsus

There is already an issue tracking that.

On Fri, Dec 9, 2016 at 12:06 PM marcinsus [email protected] wrote:

In some of cases rxBinging allows to multiple observable at a time eg. when we internally use addListener instead setListener. Maybe we should mention it in javaDoc or create annotation for it.

— You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-266066636, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEfWe7qLrWN6IeSuFzXbsxBPGQZBsks5rGYqTgaJpZM4F-uDB .

JakeWharton avatar Dec 09 '16 17:12 JakeWharton

As a workaround you can use hot observable.

private PublishSubject<Object> clickObservable = PublishSubject.create(); RxView.clicks(view).subscribe(clickObservable);

And use clickObservable.subscribe() many times

Sirelon avatar Feb 08 '17 15:02 Sirelon

Call .share() on the returned observable. Using a subject is wasteful here.

On Wed, Feb 8, 2017 at 10:28 AM Alexandr [email protected] wrote:

As a workaround you can use hot observable.

private PublishSubject<Object> clickObservable = PublishSubject.create(); RxView.clicks(view).subscribe(clickObservable);

And use clickObservable.subscribe() many times

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-278360140, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEQN9a2v-nRtSPoOr1zOZe1HKU-SVks5rad8lgaJpZM4F-uDB .

JakeWharton avatar Feb 08 '17 15:02 JakeWharton

Actually I got a use case on a seek view where multiple subscription would make sense and not sure how to deal with it, ideally I wanted :

seekview.changeEvents().filter({ start event }).subscribe { pause video player }
seekview.userChanges().subscribe { update our fancy ui with a preview image }
seekview.changeEvents().filter({ end event }).subscribe { seek to position video player }

It does not works as only the last subscribe works. Not sure how to do it except by only listening changes() and process different events by storing a state.

eboudrant avatar Oct 12 '17 18:10 eboudrant

Call publish(), set up your multiple subscriptions, and then call connect(). Or you can use .share() so long as all the subscriptions are made right away.

On Thu, Oct 12, 2017, 2:37 PM Emmanuel Boudrant [email protected] wrote:

Actually I got a use case on a seek view where multiple subscription would make sense and not sure how to deal with it, ideally I wanted :

seekview.changes().filter({ start event }).subscribe { pause video player } seekview.userChanges().subscribe { update our fancy ui with a preview image } seekview.changes().filter({ end event }).subscribe { seek to position video player }

It does not works as only the last subscribe works. Not sure how to do it except by only listening changes() and process different events by storing a state.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146#issuecomment-336227770, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEEEaXqR28esYWy8zJJAQXBU4J29bIPks5srlxggaJpZM4F-uDB .

JakeWharton avatar Oct 12 '17 18:10 JakeWharton

@JakeWharton Hey! Let's look at this samples:

Observer<Object> one = ...;
Observer<Object> two = ...;

final Observable<Unit> clicks = RxView.clicks(view);

clicks.subscribe(one);
clicks.subscribe(two);
Observer<Object> one = ...;
Observer<Object> two = ...;

final Observable<Unit> clicks = RxView.clicks(view).share();

clicks.subscribe(one);
clicks.subscribe(two);

And I am sure, that the first case is more readable and clearer. But now we need to use second because it works. I created the pull request #500 to solve this problem without .share() or other workarounds. And I can make a general solution for all similar cases. What you think about it?

nikialeksey avatar Feb 03 '19 14:02 nikialeksey

Can we add RxView.clicks() and RxView.longClicks() on a same view with same time.

dubeyvivek57 avatar Dec 03 '19 08:12 dubeyvivek57

Yes

On Tue, Dec 3, 2019, 3:11 AM dubeyvivek57 [email protected] wrote:

Can we add RxView.clicks() and RxView.longClicks() on a same view with same time.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/JakeWharton/RxBinding/issues/146?email_source=notifications&email_token=AAAQIEMGYFY4KZMVCZVP67DQWYICJA5CNFSM4BP24DA2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEFYPBYA#issuecomment-561049824, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAAQIEI7IQVN66KCRIA4RELQWYICJANCNFSM4BP24DAQ .

JakeWharton avatar Dec 03 '19 12:12 JakeWharton