Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rxJava2 Combining Single, Maybe, Completable in complex Streams

I am very excited with new RxJava Sources such as: Single, Maybe, Completable, which make your interfaces classes cleaner and prevent from a lot of mistakes during create of your 'Source' (e.g. forgetting to call onComplete())

But it requires lots of boilerplate to combine them into a complex stream.

E.g. we have common Android situation of loading and caching data. Let's assume we have 2 sources api and cache and we would like to combine it:

public interface Api {
    Single<Integer> loadFromNetwork();
}

public interface Cache {
    Maybe<Integer> loadFromCache(); //maybe because cache might not have item.
}

let's try to combine it:

final Single<Integer> result = cache.loadFromCache()
        .switchIfEmpty(api.loadFromNetwork());

it will not compile, because Maybe doesn't have overload Maybe.switchIfEmpty(Single):Single

so we have to convert everything:

final Single<Integer> result = cache.loadFromCache()
        .switchIfEmpty(api.loadFromNetwork().toMaybe())
        .toSingle();

Another possible way to combine it also requires сonversion:

final Single<Integer> result = Observable.concat(
            cache.loadFromCache().toObservable(),
            api.loadFromNetwork().toObservable()
        ).firstOrError();

So I don’t see any way to use the new sources without many transformations that add code noise and create a lot of extra objects.

Due to such issues, I can't use Single, Maybe, Completable and continue to use Observable everywhere.

So my question is:

  • What are the best practices of combining Single, Maybe, Completable.

  • Why these Sources don't have overloads to make combing easier.

  • Why these Sources don't have common ancestor and use it as
    parameter of switchIfEmpty and other methods?


P.S. Does anybody know why these classes doesn't have any common hierarchy?
From my perspective if some code can work for example with Completable it will also works fine with Single and Maybe?

like image 399
Rostyslav Roshak Avatar asked Jul 26 '17 15:07

Rostyslav Roshak


People also ask

What is the difference between Observable and single?

Observable: emit a stream elements (endlessly) Flowable: emit a stream of elements (endlessly, with backpressure) Single: emits exactly one element. Maybe: emits zero or one elements.

What is a Completable?

(kəmˈpliːtəbəl ) adjective. able to be completed.

What is single <> in Java?

RxJava (and its derivatives like RxGroovy & RxScala) has developed an Observable variant called “Single.” A Single is something like an Observable, but instead of emitting a series of values — anywhere from none at all to an infinite number — it always either emits one value or an error notification.

What is single retrofit?

Single is like promise in Javascript. A promise is an object that may produce a item or throw an error. Typically example is a network call, with retrofit you return an Observable or Flowable. You usually care for the response once you can replace this with Single<T>.


1 Answers

RxJava 2.1.4 that was released on Sep 22, 2017 adds needed overload Maybe.switchIfEmpty(Single):Single.

So in case when we would like to combine following classes:

public interface Api {
    Single<Integer> loadFromNetwork();
}

public interface Cache {
    Maybe<Integer> loadFromCache(); //maybe because cache might not have item.
}

We can finally do:

final Single<Integer> result = cache.loadFromCache()
        .switchIfEmpty(api.loadFromNetwork());

Rx team has done great job by adding extra overloads to Maybe, Single, Observable, that simplifies combining them together.

As for release 2.1.16 we have following methods for combining Maybe, Single and Completable:

Maybe: flatMapSingleElement(Single):Maybe, flatMapSingle(Single):Single, switchIfEmpty(Single):Maybe, flatMapCompletable(Completable):Completable

Single: flatMapMaybe(Maybe):Maybe, flatMapCompletable(Completable):Completable

Completable: andThen(Single):Single, andThen(Maybe):Maybe

like image 178
Rostyslav Roshak Avatar answered Sep 29 '22 20:09

Rostyslav Roshak