Search code examples
databasekotlinviewmodelobservable

Make call from modelview kotlin class to method which returns Observable


I have method which makes the database select and return Observable<>. How can I call such a method from Kotlin modelview calss?

private val _response = MutableStateFlow(Response())
val response: StateFlow<Response> = _response

suspend fun getResponse() {
        viewModelScope.launch(exceptionHandler) {
            withContext(Dispatchers.IO) {
              _response.emit(apiCall)//Type mismatch. need Response but getting Observable<Response!>!
            }
        }
}

another class

public Observable<Responnse> apiCall(){
    return cacheObservable.flatMap(response -> {return observableResponse});
};

Solution

  • There are conversions between Rx and Kotlin coroutines in the kotlinx reactive library. Add to your dependencies:

    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:1.6.4"
    // Match the coroutines version you are already using. 
    // Change rx2 to rx3 depending on which version of Rx you're using.
    

    Then you can call asFlow() on an Observable to convert it to a Flow, so your ViewModel code would become the following:

    val response: StateFlow<Response> = apiCall().asFlow()
        .flowOn(exceptionHandler)
        .stateIn(viewModelScope, SharingStarted.WhileSubscribed(5000L), Response())
    

    No need for specifying a dispatcher or creating a separate getResponse() function to initiate the call. It will begin the call the first time you collect this flow.

    I used WhileSubscribed(5000L) as an example. This allows resources to be conserved while a Fragment goes off screen, but avoids having to restart it if it's brief like during a screen rotation.