Simon Schiller
Simon Schiller

Reputation: 664

RxJava Observable that emits latest value upon subscription

I am building an Android MVVM application using RxJava2. What I want is to expose an Observable in my ViewModel, which I also can receive the last emitted value (like a BehaviourSubject). I don't want to expose a BehaviourSubject because I don't want the View to be able to call onNext().

For example, in my ViewModel I expose a date. I now want to subscribe a TextView to changes, but I also need to be able to access the current value if I want to show a DatePickerDialog with this date as initial value.

What would be the best way to achieve this?

Upvotes: 4

Views: 3034

Answers (2)

akarnokd
akarnokd

Reputation: 70007

Delegate:

class TimeSource {
    final BehaviorSubject<Long> lastTime = BehaviorSubject.createDefault(
        System.currentTimeMillis());

    public Observable<Long> timeAsObservable() {
        return lastTime;
    }

    public Long getLastTime() {
        return lastTime.getValue();
    }

    /** internal only */
    void updateTime(Long newTime) {
        lastTime.onNext(newTime);
    }
}

Upvotes: 3

azizbekian
azizbekian

Reputation: 62209

I don't want to expose a BehaviourSubject

Subject, by definition, is "an Observer and an Observable at the same time". Therefore, instead of exposing BehaviorSubject itself just expose Observable, thus client (in this case the view) won't be able to perform onNext(), but will be able to receive last emitted value.

As an alternative to subject approach you can use replay(1).autoConnect() approach. See more details concerning this approach in "RxJava by example" presentation by Kaushik Gopal.

Also, consider cache() operator (see difference of cache and replay().autoConnect() here).

Upvotes: 2

Related Questions