Step #4: Wrapping the suspend
Functions
RosterMotor
still is showing an error message, where we cannot call save()
on ToDoRepository
because:
Suspend function 'save' should be called only from a coroutine or another suspend function
That is because you cannot call a suspend
function from a normal function as we are doing here. Either:
- The caller needs to be a
suspend
function itself, or - We need to do something that accepts
suspend
functions safely
To fix that, revise save()
in RosterMotor
to be:
fun save(model: ToDoModel) {
viewModelScope.launch {
repo.save(model)
}
}
To consume a suspend
function from a normal function, you can use launch
on a CoroutineScope
. In effect, launch
says “I am willing to deal with suspend
functions, allowing my work to be suspended as needed to wait for the suspend
work to complete”.
As noted earlier, viewModelScope
is aware of the viewmodel’s lifecycle. When the viewmodel is cleared (after the user exits the fragment), any outstanding coroutines being run in the context of the viewModelScope
get canceled. For a read operation, that is fine. However, usually, we want a write operation to proceed even if the user moved along in the UI. That is why, in ToDoRepository
, we are using the appScope
CoroutineScope
as a wrapper around the Room coroutines. appScope
is set up to live for as long as our process does, so any coroutines executed from within it will get to run to completion, even if viewModelScope
gets canceled.
Prev Table of Contents Next
This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.