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 Cursor to this method's return type
I created a "custom" MutableLiveData in my DB helper this way:
class ProfileRepository @Inject internal constructor(private val profileDao: ProfileDao): ProfileRepo{
override fun insertProfile(profile: Profile){
profileDao.insertProfile(profile)
}
val mutableLiveData by lazy { MutableProfileLiveData() }
override fun loadMutableProfileLiveData(): MutableLiveData<Profile> = mutableLiveData
inner class MutableProfileLiveData: MutableLiveData<Profile>(){
override fun postValue(value: Profile?) {
value?.let { insertProfile(it) }
super.postValue(value)
}
override fun setValue(value: Profile?) {
value?.let { insertProfile(it) }
super.setValue(value)
}
override fun getValue(): Profile? {
return profileDao.loadProfileLiveData().getValue()
}
}
}
This way, I get the updates from DB and can save the Profile
object but I cannot modify attributes.
For example:
mutableLiveData.value = Profile()
would work.
mutableLiveData.value.userName = "name"
would call getValue()
instead postValue()
and wouldn't work.
Did anyone find a solution for this?
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 love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With