How can I retrieve the latest value from BehaviorSubject
on RxAndroid?
Some background info: I'm using RxJava to implement MVVM pattern. My ViewModel encapsulates "bindable properties" that are BehaviorSubject
s. I'm binding them to UI elements as observables, ensuring that the interface gets constantly updated (and thanks to using BehaviorSubject
, it's going to happen even if the subscription takes place after setting the value).
I would still like to be able to access the latest (the actual) "raw" value of the property, for business logic.
How do I do that?
Surely BehaviorSubject
caches it somehow, given that it republishes the latest value for whoever subscribes to it.
And yet BehaviorSubject.last()
only returns an Observable<T>
, and it doesn't seem to expose any methods of T
return type.
I know I could cache it myself, but it feels redundant.
I guess I could also create a throw-away subscription in my getter, only to obtain the latest value with it and then return it to the calling code, but this seems clunky.
Is there anything neater on hand?
BehaviorSubject is the answer here. Rather than a standard subject (Observable) that just emits values as they come in, a BehaviorSubject emits the last value upon subscribe() . You can also get the last value manually using the BehaviorSubjects getValue() method.
To get current value of RxJS Subject or Observable, we can use the first method. const observable = of("foo"); const hasValue = (value: any) => { return value !== null && value !== undefined; }; const getValue = <T>(observable: Observable<T>): Promise<T> => { return observable.
If you want to provide an initial value at subscription time, even if nothing has been pushed to a Subject so far, use the BehaviorSubject. If you want to have the last value replayed to an observer, even if a Subject is already closed, use the ReplaySubject(1).
BehaviorSubject is a type of subject, a subject is a special type of observable so you can subscribe to messages like any other observable. The unique features of BehaviorSubject are: It needs an initial value as it must always return a value on subscription even if it hasn't received a next()
As it turns out, the reason behind it is that RxAndroid by default depends on RxJava 1.0.4, where Subjects didn't expose getValue
nor hasValue
yet.
Thanks to @akarnokd for helping me realize that.
As it turns out, all it takes to resolve the problem is to manually add a dependency on latest version of RxJava side-by-side with RxAndroid dependency in build.gradle
. As of now that would be:
compile 'io.reactivex:rxandroid:0.24.0'
compile 'io.reactivex:rxjava:1.0.11'
See https://github.com/ReactiveX/RxAndroid/issues/171
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With