StateFlow collect does not change the data correctly

Viewed 46

I'm using MVI architecture, coroutine and flow,

when I receive the data from the API, the status changed from LOADING to SUCCESS, and when I collect the stateFlow variable it submit the recyclerView successfully while when I try to hide the loading view (progressBar, lottie) the view freeze for a moment and it does not disappear.

I tried two ways

  1. I tried to use the stateFlow in XML like this: android:visibility="@{viewModel.writersFlow.status == Results.Status.LOADING ? View.VISIBLE : View.GONE}", and of course I put lifecycleOwner = viewLifecycleOwner in onViewCreated function and I passed the viewModel to the XML

  2. change the the visibility programmatically like bellow:

Repository:

override suspend fun getWriters(): Flow<Results<BaseModel<WriterModel>?>> =
    resultFlowData(
        networkCall = {
            remoteDataSource.getResult {
                endpoints.getWriters()
            }
        }
    )

ViewModel:

 private val _writersFlow: MutableStateFlow<Results<BaseModel<WriterModel>?>> =
    MutableStateFlow(start())
val writersFlow: StateFlow<Results<BaseModel<WriterModel>?>>
    get() = _writersFlow.asStateFlow()


private fun fetchWriters() {
    viewModelScope.launch(Dispatchers.IO) {
        writerRepository.getWriters().collect {
            "writers: $it".log()
            _writersFlow.emit(it)
        }
    }
}

Fragment: here in fragment you will see the binding.loading.visibility = View.GONE in both cases (SUCCESS, ERROR)

private fun gettingWriters() {
    viewLifecycleOwner.lifecycleScope.launch {
        viewModel.writersFlow.flowWithLifecycle(lifecycle, Lifecycle.State.STARTED).collect {
            when (it.status) {
                Results.Status.SUCCESS -> {
                    writersAdapter.submitList(it.data?.response)
                    binding.loading.visibility = View.GONE
                }
                Results.Status.ERROR -> {
                    "$HOME_FRAGMENT: ${it.status}, ${it.code}, ${it.message}".log()
                    if (!it.message.isNullOrEmpty()) binding.root.snack(it.message ?: "") {}
                    binding.loading.visibility = View.GONE
                }
                Results.Status.LOADING -> {
                    binding.loading.visibility = View.VISIBLE
                }
                else -> {}
            }
        }
    }
}

In the first way the loading view does not even appear but in the second way it appears but never disappear.

0 Answers
Related