Skip to content

flatMap from Single to Completable #3865

Closed

Description

@ivacf

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);
            }
        });

Activity

  1. artem-zinnatullin commented on Apr 18, 2016

    @artem-zinnatullin
    Contributor

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

  2. added a commit that references this issue on Apr 19, 2016
    6efc2cf
  3. ivacf commented on Apr 19, 2016

    @ivacf
    Author

    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().

  4. artem-zinnatullin commented on Apr 19, 2016

    @artem-zinnatullin
    Contributor

    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?

  5. ivacf commented on Apr 19, 2016

    @ivacf
    Author

    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.

  6. artem-zinnatullin commented on Apr 19, 2016

    @artem-zinnatullin
    Contributor

    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))
  7. ivacf commented on Apr 19, 2016

    @ivacf
    Author

    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.

  8. nhaarman commented on May 31, 2016

    @nhaarman

    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) }
            )
        }
    }
  9. rstoyanchev commented on Jul 27, 2016

    @rstoyanchev

    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.

  10. akarnokd commented on Jul 27, 2016

    @akarnokd
    Member

    There is the PR #4226 for that.

  11. rstoyanchev commented on Jul 27, 2016

    @rstoyanchev

    Didn't see that thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions