Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type-safe initial value skipping? #153

Closed
JakeWharton opened this issue Sep 27, 2015 · 7 comments
Closed

Type-safe initial value skipping? #153

JakeWharton opened this issue Sep 27, 2015 · 7 comments
Labels
Milestone

Comments

@JakeWharton
Copy link
Owner

We've seen and heard struggles with the initial value behavior. Some observables emit it (property-based ones) and others do not (event-based ones).

It would be nice to encapsulate this in the type system for guarantees beyond just Javadoc.

public final class InitialValueObservable<T> extends Observable<T> {
  static <T> InitialValueObservable<T> create(InitialValueOnSubscribe<T> f) {
    return new InitialValueObservable<>(f);
  }

  private InitialValueObservable(InitialValueOnSubscribe<T> f) {
    super(f);
  }

  public Observable<T> skipInitialValue() {
    return skip(1);
  }
}
static abstract InitialValueOnSubscribe<T, V extends View> implements OnSubscribe<T> {
  private final V view;

  protected InitialValueOnSubscribe(V view) {
    this.view = view;
  }

  @Override public final void call(Subscriber<? super T> subscriber) {
    attachListener(view, subscriber);
    subscriber.onNext(initialValue(view));
  }

  protected abstract void attachListener(V view, Subscriber<? super T> subscriber);
  protected abstract T initialValue(V view);
}

Consumers could then rely on the type system for guaranteeing both that the observable would emit an initial value and that they could skip it.

RxTextView.textChanges(textView)
    .skipInitialValue()
    .switchMap(v -> suggestions(v))
    .subscribe(adapter);
@dlew
Copy link
Contributor

dlew commented Sep 28, 2015

I know we talked about this a long time ago. I've had a bit of a change of heart on it. It would be nice to indicate somehow that the Observable is expected to emit an initial value. I wonder how the folks at RxJava think about it...

My only concern is that this wouldn't be enough, since you can still use an InitialValueObservable while being completely ignorant of what it does. Just brainstorming - would it be a terrible idea to force the user to choose before using the Observable?

@JakeWharton
Copy link
Owner Author

since you can still use an InitialValueObservable while being completely ignorant of what it does

I think this can be viewed as an advantage, but I understand the sentiment.

would it be a terrible idea to force the user to choose before using the Observable?

I believe my initial proposal was opting in to the initial emission. I don't necessarily think that is the right approach either, but it certainly would be explicit.

@JakeWharton
Copy link
Owner Author

I think I'm going to make the above proposed change before 0.3 unless there's any compelling argument towards an opt-in approach.

In a casual glance through our codebase, we opt-out far less than we allow the initial value emission. That's just one example of tens of uses. I'm also not confident that I checked every operator that does have an initial value.

@konmik
Copy link

konmik commented Oct 17, 2015

I think that the cleanest and the simplest way is to use naming conventions.

RxTextView.text should emit an initial value and updates to the value.

RxTextView.textChanges should emit only updates without initial values.

RxTextView.setText returns Action1 to chain it into Observable.subscribe. But we in fact don't need such method because we have TextView::setText shortcut from retrolambda.

@JakeWharton
Copy link
Owner Author

Those overloads would just be implemented using a mechanism like what was
described above but hidden behind convention instead of being an explicit
API.

On Sat, Oct 17, 2015, 10:48 AM Konstantin Mikheev notifications@github.com
wrote:

I think that the cleanest and the simplest way is to use naming
conventions.

RxTextView.text should emit an initial value and updates to the value.

RxTextView.textChanges should emit only updates without initial values.

RxTextView.setText returns Action1 to chain it into Observable.subscribe.
But we in fact don't need such method because we have TextView::setText
shortcut from retrolambda.


Reply to this email directly or view it on GitHub
#153 (comment)
.

@JakeWharton
Copy link
Owner Author

Punting on this to 2.0 after spending the night prototyping different approaches.

@Miha-x64
Copy link

Miha-x64 commented Jul 9, 2018

I just wonder: what do you think about BehaviorSubject as a representation of view property which can be both read from and written to?
UPD: okay, this was stupid. BehaviorSubject has current value, but BehaviorSubject#map returns just an Observable and loses current value.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants