Dr4ke the b4dass
Dr4ke the b4dass

Reputation: 1204

How to pass result of livedata as a function argument using kotlin

How to use a livedata as an argument for another function? Every time I get a null value, I guess the function is called before the livedata can return hence the null value. I'm not using it from a View. I'm using it from the viewmodel, the function updateFirstName is from the viewmodel. The token comes as a Flow from the Preference Store. All answers are appreciated thanks.

    var token: LiveData<String> = appPreferenceStorage.accessToken.asLiveData()

    @ExperimentalCoroutinesApi
    private val _token: MutableLiveData<String>
        get() = token as MutableLiveData<String>
    fun updateFirstName(view: View) {
        viewModelScope.launch {

            profileRepository.updateFirstName(_token.value.toString(), "Bob", object : ProfileListener {
                override fun onSuccess(response: String?) {
                    Timber.d(response)
                }

                override fun onFailure(localizedMessage: String?) {
                    Timber.e(localizedMessage)
                }

            })
        }
    }```

Upvotes: 0

Views: 1449

Answers (2)

Andrew
Andrew

Reputation: 4712

First, there should be no "view" references inside your viewmodel, as this would couple your viewmodel with it's given view (fragment perhaps?).

So your function updateFirstName(view:View) should be changed to updateFirstName(name: String)

Second, I think you are using your repository wrong. Instead of getting a liveData from your repository and then converting it into a MutableLiveData, you should just expose a repository function, which saves your given name.

The only thing a view should do is to observe values and expose events. Nothing more.

This could be a solution:

class YourViewModel(private val repository: IYourRepositoryInterface) : ViewModel() {
   // Token should only be observed from a view and not converted to a MutableLiveData
   val token: LiveData<String> = appPreferenceStorage.accessToken.asLiveData()

   fun updateFirstName(name: String) {
      viewModelScope.launch {
          repository.updateFirstName(name) // suspend function from your repository
      }
   }
}

Furthermore, if you want to use your token inside your viewmodel and "observe" it, you can just start collecting the flow inside a function and then use its value:

val token: Flow<String> = appPreferenceStorage.accessToken

fun someFunctionThatDoesStuffWithToken() {
    viewModelScope.launch {
      token.collect { value: String ->
        // do something with its value. E.g: Write into repository, db etc.
      }
   }
}

Upvotes: 0

Fabrizio Ferrari
Fabrizio Ferrari

Reputation: 989

LiveData can be observed which gives you the ability to "read" it this way:

yourModel.token.observe(viewLifecycleOwner) { token ->

    //Here do whatever you like with "token"

}

Upvotes: 1

Related Questions