Mervin Hemaraju
Mervin Hemaraju

Reputation: 2187

Android: How to get value from LiveData without Observing it

Blockquote

I have separate classes in which I handle data fetching (Using Room) and I usually return LiveData list of objects from it and update them. Now I have a settings class where when i press "Backup", i want to have the returned data stored in a ViewModel, but the problem is that in order to get the value, I need to observe the LiveData list of objects. I do not want to observe it since i just need the value (list of objects) to perform the backup. I've tried the below method:

DAO

@Query("SELECT * FROM $DATABASE_TABLE_GOAL")
suspend fun getAllGoals_NotLive(): List<Goal>

ViewModel

var goals_NotLive: List<Goal> = ArrayList()

fun getGoalsNotLive(){
    _uiScope.launch {

        withContext(Dispatchers.IO) {
            goals_NotLive = database.goalDao.getAllGoals_NotLive()
        }
    }
}

Activity

fun getGoals(): List<Goal>{
    _viewModel.getGoalsNotLive()
    return _viewModel.goals_NotLive
}

But it stills return Size 0. What should I do?

Upvotes: 8

Views: 8671

Answers (1)

CommonsWare
CommonsWare

Reputation: 1007584

Right now, you have a DAO that has a function like this:

@Query("...")
fun gimmeData(): LiveData<SomethingOrAnother>

That requires you to observe the LiveData in order to have your query be executed. In your case, you do not want that for some scenarios. So, you need another function.

One option is to have a synchronous version of the function:

@Query("...")
fun gimmeDataSync(): SomethingOrAnother

Now, you do not need to observe a LiveData. You will need to call gimmeDataSync() on a background thread, though.

Or, since you are using Kotlin, you could add the Room dependency for coroutine support, and have:

@Query("...")
suspend fun gimmeDataAsync(): SomethingOrAnother

Once again, you do not need to observe a LiveData. You will need to call gimmeDataAsync() from inside of a coroutine, such as using viewModelScope on a ViewModel:

viewModelScope.launch(Dispatchers.Main) {
  val something = dao.gimmeDataAsync()
  // TODO do something with something
}

Upvotes: 11

Related Questions