0

I have a Room Dao method like this:

@Query("SELECT * FROM stuff WHERE x == :y")
LiveData<List<Stuff>> getStuff(int y);

And in my ViewModel I have this variable:

LiveData<List<Stuff>> stuff = myDao.getStuff(7); // note the 7!

to observe it in my Fragment:

myViewModel.stuff.observe( // lalala...

So far so good, this is working well. However, at some point I want to change the data to be stuff WHERE x == 8.

If I were to simply stuff = myDao.getStuff(8);, my fragment would still observe the LiveData object WHERE x == 7.

If I would make stuff a MutableLiveData instead, I could update the data manually, but the updates from the database would still be for WHERE x == 7 instead of 8.

Thus, how can I change what gets compared in the WHERE clause, update the data in LiveData correspondingly, have LiveData emit a corresponding event to its observers, and henceforth get updates only for the new value in the WHERE clause?

user1785730
  • 3,150
  • 4
  • 27
  • 50

2 Answers2

1

You have to do something like this in your ViewModel:

private val _stuff = MutableLiveData<List<Stuff>>(emptyList())
val stuff: LiveData<List<Stuff>>
    get() = _stuff

fun getStuff(x: Int) {
    _stuff = myDao.getStuff(x)
}

And in your fragment observe stuff.

Javlon
  • 1,108
  • 2
  • 15
  • 29
  • I don't understand the syntax of the second and third line of your code. Is that an anonimous derived object? – user1785730 May 24 '23 at 20:58
  • This is a custom getter syntax in Kotlin https://kotlinlang.org/docs/properties.html#getters-and-setters – Javlon May 25 '23 at 08:02
0

I have come across Transfomations.switchMap, which does exactly what I've been looking for.

For it to work, the parameter to compare in the WHERE clause needs to be wrapped in LiveData:

final MutableLiveData<Integer> stuffParam = new MutableLiveData<>();
stuffParam.setValue(7);

with that, only one more line of code is necessary:

final LiveData<List<Stuff>> stuff = Transformations.switchMap(stuffParam, p -> myDao.getStuff(p));

Now making stuff hold the data WHERE x == 8 is as simple as

stuffParam.setValue(8);

More information on Transformations:

How and where to use Transformations.switchMap?

What is the difference between map() and switchMap() methods?

user1785730
  • 3,150
  • 4
  • 27
  • 50