Home > Enterprise >  MutableLiveData triggered twice? Android
MutableLiveData triggered twice? Android

Time:08-30

I am using from MutableLiveData for connect to API, for first time it work true but for second time call twice.(my observe call twice)

Here is my Fragment:

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
     ....
    quizViewModel.getLoginH5P()
    quizViewModel.loginH5P.observe(viewLifecycleOwner) { response ->
        when (response) {
            is Resource.Success -> {
                hideProgressBar()
                response.data?.let {
                    Log.i("MYTAG", "AL "   it.loginurl!!)
                }
            }
            is Resource.Error -> {
                hideProgressBar()
                response.message?.let {
                    Log.i("MYTAG", "AP "   it)
                }
            }

            is Resource.Loading -> {
                showProgressBar()
                Log.i("MYTAG", "AT ")
            }
        }
    }
 .......
}

And Here is My viewModel:

class QuizViewModel(
    private val getQuizUseCase: GetQuizUseCase
) : ViewModel() {
    val loginH5P: MutableLiveData<Resource<LoginH5PEntity>> = MutableLiveData()
    fun getLoginH5P() = viewModelScope.launch(Dispatchers.IO) {
        loginH5P.postValue(Resource.Loading())
        try {
            val apiResult = getQuizUseCase.execute()
            loginH5P.postValue(apiResult)
        } catch (e: Exception) {
            loginH5P.postValue(Resource.Error(e.message.toString()))
        }
    }
}

And here is my impl:

override suspend fun getLoginH5P(): Resource<LoginH5PEntity> {
    return responseToResource(quizRemoteDatasource.getQuiz())
}


private fun responseToResource(response: Response<LoginH5PEntity>): Resource<LoginH5PEntity> {
    if (response.isSuccessful) {
        response.body()?.let { result ->
            return Resource.Success(result)
        }
    }
    return Resource.Error(response.message())
}

And here is my custom Resource:

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

I get my result twice: Log.i("MYTAG", "AL " it.loginurl!!)

CodePudding user response:

I don't know if this is necessarily the reason for your issue, but you do need to fix it. Your ViewModel has a longer lifespan than the Fragment, but you're re-fetching the data and posting it to the LiveData all over again each time the Fragment recreates the view. You can simply fetch the data once when the ViewModel is created using the liveData builder. The code is simpler using the liveData builder anyway.

class QuizViewModel(
    private val getQuizUseCase: GetQuizUseCase
) : ViewModel() {
    val loginH5P: LiveData<Resource<LoginH5PEntity>> = liveData {
        emit(Resource.Loading())
        try {
            emit(getQuizUseCase.execute())
        } catch (e: Exception) {
            emit(Resource.Error(e.message.toString()))
        }
    }
}
  • Related