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);
}
});
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
Completablecan use the result from theSingle
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!
Most helpful comment
So If I have a method in class
Alike this:Then in class
BI have a method that retrieves some data from a REST APINow from class
CI want toflatMapboth methods so whenretrieveData()completes I can pass the result tosaveData(data). Are you suggesting thatsaveData(data)should return aSingleinstead of aCompletable? I would imagine aCompletableis a better option because I don't care about the value after it's been saved.