3
RxJava 2

I have the following where I am subscribing to 2 observables it works ok. I don't think its the best way.

I only want to subscribe to the second one getSalesInfo if the first one getProductDetails meets a condition. This is just a sample of what I am trying to do. If the condition is not met then nothing more will happen.

fun main(args: Array<String>) {
    getProductDetails()
            .subscribeBy { productDetails ->
                if (productDetails.productID == 1234) {
                    getSalesInfo().subscribeBy {
                        getSalesInfo()
                                .subscribeBy { saleInfo ->
                                    println(saleInfo.salesReference)
                                }
                    }
                }
            }
}

fun getProductDetails(): Observable<ProductDetails> =
        Observable.just(ProductDetails(1234, "Product One"))

fun getSalesInfo(): Observable<SaleInfo> =
        Observable.just(SaleInfo("Sales Reference 1"))

data class ProductDetails(val productID: Int,
                          val productDescription: String)

data class SaleInfo(val salesReference: String)

Another alternative I have found is using flatmap that will return the second SaleInfo observable. I have to return a empty Observable in the else condition which doesn't look right. Is there a better way?

getProductDetails()
            .flatMap { productDetails: ProductDetails ->
                if (productDetails.productID == 1234) {
                    getSalesInfo()
                }
                else {
                    Observable.empty()
                }
            }
            .subscribeBy { saleInfo ->
                println("Using flatmap ${saleInfo.salesReference}")
            }

Many thanks for any suggestions

ant2009
  • 27,094
  • 154
  • 411
  • 609
  • 3
    In that case you can use `filter()` combining with `flatMap()`. Similar like that `getProductDetails().filter { it.productID == 1234 }.flatMap {getSalesInfo() }.subscribe { saleInfo -> println("Using flatmap ${saleInfo.salesReference}")}` – ConstOrVar Mar 09 '20 at 20:02
  • 2
    There might be a more natural reactive solution to your problem than subscribing to a second observable at the first observable emits a particular object. Such as combining Observables, applying filter(), etc. Can you give a little more info on what you're trying to achieve? – TrogDor Mar 13 '20 at 16:02

1 Answers1

2

I would suggest that your first method is better. It describes exactly what you want it to do, and has the benefit that if you wanted to take some action when productID != 1234, you can have a different callback for the RX action that is taken. While they do essentially the same thing, there is probably a slight overhead for the second one due to the flatMap, and it also reduces flexibility.

Hack5
  • 3,244
  • 17
  • 37