Search code examples
androidkotlinviewmodelandroid-livedata

How change MutableLiveData value inside ViewModel


I need to change the value of MutableLiveData in my ViewModel, but I can't make it because the value is equal to null, I think need to establish an observer change it inside that, but I don't know how to do it and whether it's a good idea.

AudioRecordersListViewModel

class AudioRecordersListViewModel() : ViewModel() {
    var audioRecordsLiveData: MutableLiveData<MutableList<AudioRecordUI>> = MutableLiveData();
    private var audioRecordDao: AudioRecordDao? = null

    @Inject
    constructor(audioRecordDao: AudioRecordDao) : this() {
        this.audioRecordDao = audioRecordDao
        viewModelScope.launch {
        val liveDataItems = audioRecordDao
                .getAll().value!!.map { item -> AudioRecordUI(item) }
                .toMutableList()

            if (liveDataItems.size > 0) {
                liveDataItems[0].isActive = true
            }

            audioRecordsLiveData.postValue(liveDataItems)
        }
    }
}

AudioRecordDao

@Dao
interface AudioRecordDao {
    @Query("SELECT * FROM AudioRecordEmpty")
    fun getAll(): LiveData<MutableList<AudioRecordEmpty>>
}

Solution

  • First of all, using !! is not a good idea it can easily lead to NullPointer Exception, us ? instead.

    You can set an empty list on your LiveData and add new data to that List:

    var audioRecordsLiveData: MutableLiveData<MutableList<AudioRecordUI>> = MutableLiveData();
    
    init {
        audioRecordsLiveData.value = mutableListOf()
    }
    

    If you need to observe that LiveData:

    mViewModel.mLiveData.observe(this, Observer { list ->
            if (list.isNotEmpty()) {
                //Update UI Stuff
            }
    })
    

    never set your LiveData inside Fragment/Activity

    If you need to update your LiveData:

    mViewModel.onSomethingHappened()
    

    Inside ViewModel:

    fun onSomethingHappened() {
      ...
      ...
      ...
      mLiveData.value = NEW_VALUE
    }
    

    If you want to update your LiveData from another thread use:

    mLiveData.postValue()