1

I try to write a transformation function which is used with compose() in order to reduce boilerplate code. It's pretty simple like this:

    fun <R> withSchedulers(): ObservableTransformer<R, R> {
        return ObservableTransformer {
            it.subscribeOn(Schedulers.io())
              .observeOn(AndroidSchedulers.mainThread())
        }
    }

So everytime I want to subscribe to anything on ioThread and listen the result on mainThread, it's just few lines of code:

    Observable.just(1)
        .compose(MyUtilClass.withSchedulers())
        .subscribe()

But there isn't Observable only, but we also have Single, Completable, Maybe and Flowable. So every time I want to combine them with my withSchedulers() function, I have to transform it into the new type (which I don't expect).

For example,

Completable.fromAction { 
        Log.d("nhp", "hello world")
    }//.compose(MyUtilClass.withSchedulers()) <-- This is not compiled
            .toObservable() <--- I have to transform it into Observable
            .compose(MyUtilClass.withSchedulers())
            .subscribe()

So my question is, is there any way to write the above function to use with compose() for any kind of Observable (Single, Completable,...) ? Or we have to write different functions which use ObservableTransformer, SingleTransformer, ....?

phatnhse
  • 3,870
  • 2
  • 20
  • 29

1 Answers1

4

I created a helper method using reified type :

inline fun <reified T> withSchedulers(): T {
    when (T::class) {
        ObservableTransformer::class  -> return ObservableTransformer<Unit, Unit> {
            it.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        } as T
        SingleTransformer::class      -> return SingleTransformer<Unit, Unit> {
            it.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        } as T
        CompletableTransformer::class -> return CompletableTransformer {
            it.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread())
        } as T
    }
    throw IllegalArgumentException("not a valid Transformer type")
}

Examples :

    Observable.just("1", "2")
            .compose(withSchedulers<ObservableTransformer<String, String>>())
            .subscribe(System.out::println)

    Single.just(3)
            .compose(withSchedulers<SingleTransformer<Int, Int>>())
            .subscribe(Consumer { println(it) })

    Completable.defer { Completable.complete()  }
            .compose(withSchedulers<CompletableTransformer>())
            .subscribe { println("completed") }

Output :

1
2
3
completed

Probably other ways of doing this, but this came to mind.

Mark
  • 9,604
  • 5
  • 36
  • 64
  • I think about this too. RxJava2 doesn't provide an inheritance design but composition. So I think this is the only way to achieve that. Thank you. Mark this as accepted answer. – phatnhse Jan 04 '19 at 02:52
  • why not make use of Kotlin extension functions for that? – M. Wojcik May 06 '21 at 14:28
  • You could nothing wrong with that, but the original question specially included `compose()` and Transformer, extension functions would not use a Transformer, it'll only be syntactic sugar around the observable / flowable. – Mark May 06 '21 at 17:43