How would I then trigger this from viewmodel / rec...
# coroutines
u
How would I then trigger this from viewmodel / receive result?
p
What you need is to switch the coroutine context in your repository so that it does not get cancelled when viewmodel is destroyed. Your repository should have a scope of its own and if you do some sync operations that should not be cancelled on vm destroy then sync operations should run on repository scope instead of vm scope. These are good articles to read about scopes and their context: https://medium.com/@elizarov/the-reason-to-avoid-globalscope-835337445abc https://medium.com/@elizarov/coroutine-context-and-scope-c8b255d59055
u
Im confused, youre saying for my sync I should have something like
Copy code
Repository {
    fun sync() {
       repoScope.launch { .. }
    }
}
right? but then sync is a normal function, how can I let vm know when sync is done, etc?
s
One way is to call
join()
on the
Job
returned by
launch {...}
. This means, though, that
sync()
must become
suspend
.
Or, instead of
launch
, use
async<Unit>
, then
await()
the
Unit
result or a possible Exception.
p
right? but then sync is a normal function, how can I let vm know when sync is done, etc?
Usually these kind of operations are done using channels to retrieve the result. After the sync operation is done it should send the updated data through the channel. This way if you have multiple calls to sync you will always have the most recent data in your UI since you have a single source of truth. If you really need the result then you should use
withContext()
and pass in the repo scope context. This ways the block will not be cancelled by vm destroy.
u
but if I sideffect to channels, then I lose composability right?