I currently have a way that works, but it uses a boolean that is external to the coroutine, and it just feels like there must be a more elegant way to do it. I plan on using this pattern in many places in my app so I want it to be "right". Currently I solve the problem like this:
private loadingFinished: Boolean = false
private fun loadData() {
showLoading.value = false
loadingFinished = false
viewModelScope.launch {
delay(500)
if (!loadingFinished)
showLoading.value = true
}
viewModelScope.launch {
try {
data = api.thisIsASuspendFunction
updateUI.call()
loadingFinished = true
showLoading.value = false
}
catch (e: Exception){
loadingFinished = true
showLoading.value = false
showError.value = errorHelper.getErrorMessageType(e)
}
}
}
This works exactly as I expect it to right now: If the api call takes longer than half a second, the progress spinner shows and is stopped once the suspend function finishes. But is there a more correct way to accomplish this?
You can use job cancellation for it:
private fun loadData() {
showLoading.value = false
viewModelScope.launch {
val loadingJob = launch {
delay(500)
showLoading.value = true
}
try {
data = api.thisIsASuspendFunction
loadingJob.cancel()
updateUI.call()
showLoading.value = false
}
catch (e: Exception){
loadingJob.cancel()
showLoading.value = false
showError.value = errorHelper.getErrorMessageType(e)
}
}
}