Search code examples
androidkotlinandroid-livedata

How to omit the last value of a liveData when the fragment / activity is recreated?


I have a problem with liveData in a particular case. When the response from a http service is Code = 2, it means that the session token has expired. In that case I navigate to the LoginFragment to login the user again. If the user logs in, then I return to the fragment which was previously and when I start to observe the liveData in onViewCreated function, it gives me its last value which is: Code = 2, so the Application navigates back to the login, which is wrong.

I have a Sealed Class:

sealed class Resource<T>(
    var data: T? = null,
    val message: String? = null,
    val Code: Int? = null

) {
    class Success<T>(data: T?) : Resource<T>(data)
    class Error<T>(message: String, code: Int? = null) : Resource<T>(message = message, Code = code)
    class Loading<T> : Resource<T>()
}

This is the code on the ViewModel:

val mLiveData: MutableLiveData<Resource<Data>> = MutableLiveData()

fun getData() {
    viewModelScope.launch {
        mLiveData.postValue(Resource.Loading())
        try {
            if (app.hasInternetConnection()) {
                // get Data From API
                val response = repository.getData()
                if(response.isSuccessful){
                    mLiveData.postValue(Resource.Success(parseSuccessResponse(response.body())))
                } else {
                    mLiveData.postValue(Resource.Error(parseErrorResponse(response.body())))
                }
            } else {
                mLiveData.postValue(Resource.Error("Connection Fail"))
            }
        } catch (t: Throwable) {
            when (t) {
                is IOException -> mLiveData.postValue(Resource.Error("Connection Fail"))
                else -> mLiveData.postValue(Resource.Error("Convertion Fail"))
            }
        }
    }
}

This is the code on the fragment, observeForData() is called in onViewCreated function:

private fun observeForData() {
    mLiveData.getData.observe(viewLifecycleOwner, Observer { response ->
        when (response) {
            is Resource.Success -> {
                isLoading = false
                updateUI(response.data)
            }
            is Resource.Error -> {
                isLoading = false
                if (response.Code == 2) {
                    // Token Expired
                    navigateToLogin()
                } else {
                    showErrorMessage(response.message)
                }
            }
            is Resource.Loading -> {
                isLoading = true
            }
        }
    })
}

How can i solve this? Is there a way to remove the last value or state from a liveData when the fragment is destroyed when navigating to the LoginFragment?

Thank you.


Solution

  • To change last updated value for live data,You can set "Resource" class with default null values when onDestroy().

    onDestroy(){
    //in java ,it will be new Resource instance
    Resource resourceWithNull=new Resource();
    
    mLiveData.setValue(resourceWithNull);
    }
    

    when you relaunch the fragment live data will emit Resource with null value as response.

    Then You can write your code with in observer

    if(response.data!=null)
    {
    //your code
    
    }