kotlinandroid-jetpack-composekotlin-coroutinesdesktop-applicationcancellation

Use "remember" to store a function to cancel coroutine jobs


How can I remember a function in Jetpack Compose? I'd like the search function to return another function that will cancel its two jobs so that when the user hits search again it won't start another parallel search but cancel the previous one:

This is the search function:

fun search(coroutineScope: CoroutineScope): () -> Unit {

        payments.clear()

        val channel = Channel<Payment>()

        val producer = coroutineScope.launch(Dispatchers.IO) {
            println("Query started.")
            fetchPayments(filter, channel)
            println("Query finished.")
        }
        val consumer = coroutineScope.launch {
            updatePayments(channel, payments)
            println("Updated: ${payments.size}")
        }
        return fun() {
            producer.cancel()
            consumer.cancel()
        }
    }

This calls search and needs to store the cancellation function:

@Composable
fun Browser() {

    val coroutineScope = rememberCoroutineScope()
    val cancelSearch = remember {} // <-- What goes in here?

    Button(onClick = { 
            cancelSearch.value() // <-- this needs to cancel the previouis search (if any)
            cancelSearch = model.search(coroutineScope) // updates the cancellation function
        }, 
        modifier = Modifier.weight(1f)) {
            Text("Search")
        }
    )
}

Solution

  • Here is a way to keep function in state.

    var cancelSearch by rememberSaveable { mutableStateOf<(() -> Unit)?>(null) }
    
    Button(onClick = {
        cancelSearch?.invoke()
        cancelSearch = search(coroutineScope)
    }