Arek Kubiński
Arek Kubiński

Reputation: 269

After updating LiveData my switchMap don't want to trigger

Like in title, I have _token

private val _token = MutableLiveData<String>()

that should update

val userPackages: LiveData<List<Packages>> = Transformations.switchMap(_token) {
        packagesLiveData(it)
    }

after i use

fun setToken(token: String) {
        Log.d(TAG, "setToken: $token")
        _token.postValue(token)
    }

from this Log.D I know that im getting valid string i tried

_token.value = token

but nothing changed I see from this function that im calling inside switchmap

private fun packagesLiveData(string: String): LiveData<List<Packages>> {
        Log.d(TAG, "switchMap: $string")
        return liveData {
            tvRepository
                .getUserPackage(string)
                .asLiveData()
        }
    }

that im not getting any change (cos this function not being called at all) or if i inicialize value of _token to any string then i see it being called twice but with this initialized value and not with the value from _token.value that i confirmed while testing is indeed changing but switchmap can never access

EDIT

It looks like i just didn't observed my liveData but now when i try to do this I'm getting error that i don't have get function for this val I'm getting my model in my fragment from this

private val tvViewModel: TvViewModel by viewModels()

and this is how my observer looks like

tvViewModel.userPackages.observe(viewLifecycleOwner, {
            Log.d(TAG, "setTvObservers: ${it?.get(0)}")
        })

Requested ViewModel:

@HiltViewModel
class TvViewModel @Inject constructor(
    private val tvRepository: TVRepository
) :
    ViewModel() {
    companion object {
        const val TAG = "TvViewModel"
    }

    private val _tvPath = MutableLiveData<String>()
    private val _token = MutableLiveData<String>()
    val tvPath: LiveData<String> = _tvPath

    val userPackages: LiveData<List<Packages>> = Transformations.switchMap(_token) {
        packagesLiveData(it)
    }

    fun setTvPath(path: String) {
        _tvPath.postValue(path)
    }

    fun setToken(token: String) {
        Log.d(TAG, "setToken: $token")
        _token.postValue(token)
    }

    private fun packagesLiveData(string: String): LiveData<List<Packages>> {
        Log.d(TAG, "switchMap: $string")
        return liveData(Dispatchers.IO) {
            tvRepository
                .getUserPackage(string)
                .asLiveData()
        }
    }
}

Upvotes: 0

Views: 970

Answers (1)

mehul bisht
mehul bisht

Reputation: 742

Are you observing this LiveData, i.e. userPackages somewhere?

Because as mentioned here,

The transformations aren't calculated unless an observer is observing the returned LiveData object.

So make sure you are observing userPackages somewhere, if it still doesn't work do tell, we'll try to find a solution again :)

EDIT:

By looking at the way you were observing the LiveData using viewLifecycleOwner, it seems that you are observing it inside a fragment. So, inside a fragment, you do not get the ViewModel by calling by viewModels(). Instead, you need to use by activityViewModels<TvViewModel>

if it still doesn't work let me know, we'll try to look again :)

LATEST UPDATE

ok so even though this doesn't give any compile-time warnings, but inside your packagesLiveData, the tvRepository.getUserPackage(string).asLiveData() returns a LiveData, and you are using livedata wrapper again around it. What you need to do is something like this:

private fun packagesLiveData(string: String): LiveData<List<Packages>> {
    Log.d(TAG, "switchMap: $string")

    return tvRepository
            .getUserPackage(string)
            .asLiveData()
}

Upvotes: 1

Related Questions