Apparently, Room is not able to handle MutableLiveData and we have to stick to LiveData as it returns the following error:
error: Not sure how to convert a Curso
Since Room doesn't support MutableLiveData
and has support for LiveData
only, your approach of creating a wrapper is the best approach I can think of. It will be complicated for Google
to support MutableLiveData
since the setValue
and postValue
methods are public
. Where as for LiveData
they are protected
which gives more control.
In your repository you can get LiveData
and transform it to MutableLivedata
:
var data= dao.getAsLiveData()
return MutableLiveData<T>(data.value)
Call me crazy but AFAIK there is zero reason to use a MutableLiveData for the object that you received from the DAO.
The idea is that you can expose an object via LiveData<List<T>>
@Dao
public interface ProfileDao {
@Query("SELECT * FROM PROFILE")
LiveData<List<Profile>> getProfiles();
}
Now you can observe them:
profilesLiveData.observe(this, (profiles) -> {
if(profiles == null) return;
// you now have access to profiles, can even save them to the side and stuff
this.profiles = profiles;
});
So if you want to make this live data "emit a new data and modify it", then you need to insert the profile into the database. The write will re-evaluate this query and it will be emitted once the new profile value is written to db.
dao.insert(profile); // this will make LiveData emit again
So there is no reason to use getValue
/setValue
, just write to your db.
If you really need to, then you can use the mediator trick.
In your ViewModel
val sourceProduct: LiveData<Product>() = repository.productFromDao()
val product = MutableLiveData<Product>()
val mediator = MediatorLiveData<Unit>()
init {
mediator.addSource(sourceProduct, { product.value = it })
}
In fragment/activity
observe(mediator, {})
observe(product, { //handle product })