I have this real world scenario.
I have a ReaderConfig object, which is a dumb tuple of ReaderTheme, ReaderFont, ReaderFontSize. Its changes will trigger the readerConfigObservable which then redraws stuff.
So the solution sofar is
combineLatest(themeObservable, fontObservable, fontSizeObservable,
(theme, font, fontSize) -> new ReaderConfig(theme, font, fontSize))
However, because this is android, ReaderTheme sets some android R.theme. stuff, which need to restart Activity for them to take effect. So I need to expose the themeObservable by it self also
themeObservable.subscribe(__ -> activity.recreate())
Since it restarts the activity, theres no need for it to trigger the combineLatest, which triggers redraw and allocates resources, only to be disposed of 1 second later because of the restart.
So only fontObservable and fontSizeObservable changes should trigger the combineLatest, HOWEVER I do need the latest themeObservable value in order to construct the ReaderConfig object.
My workaround is this
public Observable<ReaderConfig> readerConfigObservable() {
return Observable.combineLatest(
mFontRelay, mFontSizeRelay, (__, ___) -> createReaderConfig());
}
public ReaderConfig createReaderConfig() {
return new ReaderConfig(mThemeRelay.getValue(), mFontRelay.getValue(), mFontSizeRelay.getValue());
}
So basically it pulls the themeObservable in the combiner function which is not really reactive, is there any proper solution for this exception use case?
I think this could be solved using withLatestFrom(...)
:
Merges the specified ObservableSource into this ObservableSource sequence by using the resultSelector function only when the source ObservableSource (this instance) emits an item.
See the marbles diagram: http://rxmarbles.com/#withLatestFrom
Example:
.combineLatest(fontObservable, fontSizeObservable,
(font, size) -> new FontConfig(font, size))
.withLatestFrom(themeObservable,
(fontConfig, theme) -> new ReaderConfig(theme, fontConfig.font, fontConfig.size))