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