Search code examples
androidrx-javareactive-programmingrx-kotlin

RxJava: How to extract same observeOn from different functions?


Basically my Android app have some meta data which need to report to backend server in different scenarios:

data class SearchMetaData(
    val searchId: String?,
    val isRateLimit: Boolean
)

In order to make the code clean, I make the minimal case as follows. All the report logic are similar, each of the function subscribe the metadata provider and get the value that need to report.

fun logEvent1() {
    fetchMetaData().observeOn(schedulers.mainThread()).subscribe({ metadata ->
        ...//lots of other events data here
        val sessionMetadata = SessionMetadata()
        sessionMetadata.id = metadata.searchId
        sessionMetadata.limiit = metadata.isRateLimit
        event1.session = sessionMetadata
        ...
        report(event1)
    })
}

fun logEvent2() {
    fetchMetaData().observeOn(schedulers.mainThread()).subscribe({ metadata ->
        ...//lots of other events data here
        val sessionMetadata = SessionMetadata()
        sessionMetadata.id = metadata.searchId
        sessionMetadata.limiit = metadata.isRateLimit
        event2.session = sessionMetadata
        ...
        report(event2)
    })
}

fun logEvent3() {
    fetchMetaData().observeOn(schedulers.mainThread()).subscribe({ metadata ->
        ...//lots of other events data here
        val sessionMetadata = SessionMetadata()
        sessionMetadata.id = metadata.searchId
        sessionMetadata.limiit = metadata.isRateLimit
        event3.session = sessionMetadata
        ...
        report(event3)
    })
}

My concern is every time we change the schema of metadata, we need to update all the logEventX , I was wondering if maybe we could extract all the subscribe in different functions and get the metadata?


Solution

  • Consider an extension function using compose and doOnSuccess

    Single<MetaData>.handleLogging() : Single<MetaData>{
      return compose{
         it.doOnSuccess{ metaData ->
             val sessionMetadata = SessionMetadata()
             sessionMetadata.id = metadata.searchId
             sessionMetadata.limiit = metadata.isRateLimit
             report(sessionMetaData)
         }
      }
    }
    
    //usage
    fetchMetaData().handleLogging().subscribe{
      //other uncommon logic here.
    }