https://kotlinlang.org logo
#compose
Title
# compose
h

Hyun

06/24/2020, 5:00 AM
Hi, I need an advice. I would like to call suspend function on
TextButton.onClick
. as
onClick
is not Composable. I can’t use
launchInComposition
so, I tried the below. but I’m not sure if this is proper approach or not. I searched on this channel but. it was difficult to find the discussion.
Copy code
scope = remember { CoroutineScope(SupervisorJob() + Dispatchers.Main.immediate) }
onDispose { scope.cancel() }

TextButton(onClick={ scope.launch { doSuspendFunction() }})
what is the best approach on this case?
l

Leland Richardson [G]

06/24/2020, 5:26 AM
good question. We might want to provide an API like this but we don’t yet. Haven’t tested anything or tried this out. but something close to this might be a good interim solution. Ideally we provide something that allows you to use the corountinescope that
launchInComposition
uses which will work a little bit better but for the most part I think this would work okay:
Copy code
class ComposableCoroutineScopeImpl(
    val context: CoroutineContext
) : CoroutineScope, CompositionLifecycleObserver {
    val job = Job()
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Default + job
    override fun onEnter() {}
    override fun onLeave() { job.cancel() }
}

@Composable
fun composableCoroutineScope(
    context: CoroutineContext = EmptyCoroutineContext
): CoroutineScope = remember {
    ComposableCoroutineScopeImpl(context)
}
👍 4
h

Hyun

06/24/2020, 5:42 AM
@Leland Richardson [G] I’m really appreciated for the answer.🙏🙏🙏 I’ll do below with your code.
Copy code
scope = composableCoroutineScope()

TextButton(onClick={ scope.launch { doSuspendFunction() }})
z

Zach Klippenstein (he/him) [MOD]

06/24/2020, 2:20 PM
Are the contracts for
onDispose
and
CompositionLifecycleListener.onLeave
different? I thought the former would not get called if the composition failed before committing, and if that's true for the latter as well that means this code could leak the job/coroutine. https://kotlinlang.slack.com/archives/CJLTWPH7S/p1591660760450000?thread_ts=1591653158.447300&cid=CJLTWPH7S
l

Leland Richardson [G]

06/24/2020, 4:12 PM
hmm. tbh i didn’t think too carefully when i wrote this code. It’s possible if the composition got cancelled that it would have the wrong semantics, but if it got canceled then the onClick handler would never have a chance to get fired so i’m not sure this is an issue?
👍 1
you shouldn’t call
scope.launch
in the composition, only in an event handler or something like the original question had