DominikS
DominikS

Reputation: 381

Proper way to pass LiveData in ViewModel taken from suspended Repository

I'm wrapping my head around Kotlin coroutines and LiveData. I want to do really basic use case where ViewModel returns LiveData taken from Repository suspended function, which returns LiveData as well.

Repository function signature:

suspend fun getAll() : LiveData<List<Mountain>> 

It can't simply do that:

fun getMountains() : LiveData<List<Mountain>> {
  return mountainsRepository.getAll()
}

because the compiler states that suspend function should be called from coroutine or another suspend function. I came up with 2 ugly solutions, but I know they aren't elegant:

1 Solution with runBlocking

fun getMountains() : LiveData<List<Mountain>> = runBlocking { mountainsRepository.getAll() }

2 Solution with nullable LiveData

fun getMountains() : LiveData<List<Mountain>>?{
    var mountains : LiveData<List<Mountain>>? = null
    viewModelScope.launch{
        mountains = mountainsRepository.getAll()
    }
    return mountains
}

How can I do this properly?

Upvotes: 9

Views: 4351

Answers (2)

Alex Krafts
Alex Krafts

Reputation: 525

There is a liveData builder that can call suspend functions in its body. So your view model function can look like

fun getMountains() = liveData {
   emit(mountainsRepository.getAll()) 
}

make sure you are using at least

implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0"

And as Lena mentioned - removing suspend from your repository getAll() function do not make it blocking.

Having

fun getAll() : LiveData<List<Mountain>> 

in your repo, and

fun getMountains() = mountainsRepository.getAll()

in your view model, could be a better way to achieve the same goal

Upvotes: 13

Lena Bru
Lena Bru

Reputation: 13947

remove the suspend keyword from suspend fun getAll() : LiveData<List<Mountain>>

LiveData in Room is already asynchronious and it will work just fine in the background, if you are using Room to get your live data.

Room, Coroutines, LiveData

Upvotes: 0

Related Questions