Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert LiveData to MutableLiveData

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?

like image 718
kike Avatar asked Jun 20 '18 08:06

kike


1 Answers

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.

like image 68
EpicPandaForce Avatar answered Sep 23 '22 05:09

EpicPandaForce