Search code examples
androidandroid-roomandroid-livedata

Changing LiveData WHERE clause


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?


Solution

  • 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?