Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to ignore one of observables in combineLatest, but have its latest available in the combiner function?

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?

like image 406
urSus Avatar asked Dec 03 '25 20:12

urSus


1 Answers

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))
like image 162
ESala Avatar answered Dec 05 '25 11:12

ESala



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!