Ian
Ian

Reputation: 334

Kotlin: How to change values of MutableLiveData in ViewModel without using getters and setters

Here is my viewmodel:

class MyProfileEditSharedViewModel : ViewModel() {
    val question = MutableLiveData<String>()
    val answer = MutableLiveData<String>()

    fun setQuestion (q: String) {
        question.value = q
    }

    fun setAnswer (a: String) {
        answer.value = a
    }
}

I set the data using setQuestion and setAnswer like this:

viewModel.setQuestion(currentUserInList.question)
viewModel.setAnswer(currentUserInList.answer)

I try to get question and answer from the ViewModel like this:

val qnaQuestionData = communicationViewModel.question as String
val qnaAnswerData = communicationViewModel.answer as String

Compiler says I cannot cast MutableLiveData to string. Should I make a separate getter like my setter? I heard that you don't need to use getters and setters in kotlin, is there anyway to edit val question and val answer in my viewmodel without using getters and setters?

Thank you!!

Upvotes: 2

Views: 6137

Answers (2)

Mohsen Beiranvand
Mohsen Beiranvand

Reputation: 1022

You can't cast it to String because the type of object is MutableLiveData, but you can access the value with .value property

val qnaQuestionData = communicationViewModel.question.value
val qnaAnswerData = communicationViewModel.answer.value

in this case, may facing errors about MutableLiveData initialization.

another way is observing the LiveData for changes:

communicationViewModel.question.observe(this, Observer{ data->
 ...
})

Or if you have not accessed to any lifecycle owner

communicationViewModel.question.observeForever(Observer{ data->
 ...
})

but please remember to remove the observer through removeObserver method

  • for setting the values it's better to use properties directly or binding way
communicationViewModel.question.postValue("some new value")

Or

communicationViewModel.question.value = "some new value"
  • Suggestion for MutableLiveData properties:
val question: MutableLiveData<String> by lazy { MutableLiveData<String>() }
val answer: MutableLiveData<String> by lazy { MutableLiveData<String>() }

https://developer.android.com/reference/android/arch/lifecycle/LiveData

Upvotes: 3

Edward
Edward

Reputation: 143

Create some sort of getter method in your ViewModel

fun getQuestion(): LiveData<String> {
        return question //this works because MutableLiveData is a subclass of LiveData
}

Then, you can observe the value in whatever class you care about the value. ie:

communicationsViewModel.getQuestion().observe(this, Observer {
       //do something with the value which is 'it'. Maybe qnaQuestionData = it
}

Note if you're trying to observe the value from a fragment or something, you will have to change the parameter this, to viewLifecycleOwner

Upvotes: 1

Related Questions