In my example, I need to perform a process and if it is successful, the app should navigate to the next page.
The first approach uses viewmodel scope on a non suspend function and then uses a callback to let the UI know that the process is complete. The second approach is declaring a coroutine scope in the UI level and then making the viewmodel a suspend function.
Which would be the right approach for my scenario? What's the advantage of each approach over the other? Is there a particular scenario where one approach is more applicable than the other?
First approach:
UI:
Button(
onClick = {
vm.process(
onSuccess = { navcontroller.Navigate("nextpage") },
onFail = { errorMessage.value = it }
)
}
)
ViewModel:
fun process() {
viewmodelScope.launch {
val err = process()
if(err.isBlank()) {
onSuccess()
} else {
onFail(err)
}
}
}
Second approach?
UI:
val scope = rememberCoroutineScope()
Button(onClick = {
scope.launch {
val err = vm.process()
if(err.isBlank()) {
navController.navigate("nextPage")
} else {
errorMessage.value = err
}
}
})
ViewModel:
suspend fun process() : String {
val err = process()
if(err.isBlank()) {
onSuccess()
} else {
onFail(err)
}
}
Qs: What's the difference between rememberCoroutineScope()
& viewmodelscope
?
The rememberCoroutineScope()
is tied to the lifecycle of the composable & the ViewModelScope
is the same as the lifecycle scope, the only difference is that the coroutine in this scope will live as long as the view model is alive.
i.e
On orientation change, the coroutines in ViewModelScope
will live but the lifecycle
scope's coroutines will die/end.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With