Rxjava: flatMap from Single to Completable

Created on 18 Apr 2016  路  10Comments  路  Source: ReactiveX/RxJava

Is there an easy way of doing a flatMap from a Single to a Completable?

Currently I need to do something like this:

 Completable saveData(Data data) {
      ... 
 }

 Single.just(data)
        .flatMapObservable(new Func1<Data, Observable<?>>() {
            @Override
            public Observable<?> call(Data data) {
                return saveData(data).toObservable();
            }
        })
        .toCompletable();

I think It would be good to have an operator like Single.flatMapCompletable() so we could do:

Single.just(data)
        .flatMapCompletable(new Func1<Data, Completable>() {
            @Override
            public Completable call(Data data) {
                return saveData(data);
            }
        });
Feature-Request PR welcome

Most helpful comment

So If I have a method in class A like this:

Completable saveData(Data data) {
     // Creates and returns a Completable that saves some data in local storage
}

Then in class B I have a method that retrieves some data from a REST API

Single<Data> retrieveData() {
     // Creates and returns a Single that gets some data
}

Now from class C I want to flatMap both methods so when retrieveData() completes I can pass the result to saveData(data). Are you suggesting that saveData(data) should return a Single instead of a Completable? I would imagine a Completable is a better option because I don't care about the value after it's been saved.

All 10 comments

At the moment you can pass the Single to Completable.fromSingle(), I'll submit a PR for Single.toCompletable().

I'm not sure this issue is resolved by adding Single.toCompletable()?

My question was how to "link" a Single to a Completable using an operator like flatMap so that the Completable can use the result from the Single. If I transform my source Single to a completable using Single.toCompletable() then the value is lost.

My suggestion is to add Single.flatMapCompletable().

so that the Completable can use the result from the Single

Completable is value-less type, you won't be able to use result from Single or Observable. It was created to replace Observable<Void> / Single<Void> when you just need to perform some side-effect work.

Can you use Single instead of Completable?

So If I have a method in class A like this:

Completable saveData(Data data) {
     // Creates and returns a Completable that saves some data in local storage
}

Then in class B I have a method that retrieves some data from a REST API

Single<Data> retrieveData() {
     // Creates and returns a Single that gets some data
}

Now from class C I want to flatMap both methods so when retrieveData() completes I can pass the result to saveData(data). Are you suggesting that saveData(data) should return a Single instead of a Completable? I would imagine a Completable is a better option because I don't care about the value after it's been saved.

If you want final result to be Completable then one way is to do:

Completable result = retrieveData()
  .flatMap(data -> saveData(data).toSingle(() -> "")) // Just emit something.
  .toCompletable()

If you want final result to be Single then one way to do this:

Single<Data> result = retrieveData()
  .flatMap(data -> saveData(data).toSingle(() -> data))

Yeah, that makes sense. I want the final result to be a Completable so the first option would work for me. However it seems a bit redundant having to call toSingle() and then call toCompletable(). That's why I was thinking that adding a new operator like single.flatMapCompletable() could be useful.
Thanks.

A simple extension function in Kotlin would be the following:

fun <T> Single<T>.flatMapCompletable(producer: (T) -> Completable): Completable {
    return Completable.create { subscriber ->
        subscribe(
              { producer(it).subscribe(subscriber) },
              { subscriber.onError(it) }
        )
    }
}

Could this please be re-opened? The scenario with a save method seems like a prime use case for Completable. To say that you can't go from Single to a nested save is pretty hard to accept.

There is the PR #4226 for that.

Didn't see that thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

philleonard picture philleonard  路  3Comments

nltran picture nltran  路  4Comments

ZakTaccardi picture ZakTaccardi  路  3Comments

wangjingling picture wangjingling  路  3Comments

yubaokang picture yubaokang  路  3Comments