The app should not search immediately when the tex...
# compose
m
The app should not search immediately when the text changes, but only after an interval.
Copy code
var result by remember { mutableStateOf(emptyList<String>()) }
val (query, changeQuery) = remember { mutableStateOf("") }
LaunchedEffect(subject = query) {
    delay(300L)
    stations = getResultFromWebServer(query)
}
BasicTextField(value = query, onValueChange = changeQuery)
Is this the correct way to do it?
📌 1
z
I think calling
getResultFromWebServer
should be ViewModel’s responsibility. You can use
StateFlow
on
viewModel
and observe that on
init
block to fire the rest api call.
Copy code
class MyViewModel: ViewModel() {
    private val _query = MutableStateFlow("")
    val query: StateFlow<String> get() = _query

    init {
        viewModelScope.launch {
            query.debounce(300).drop(1).collect { key ->
                getResultFromWebServer(key)
            }
        }
    }
}
👍 2
t
I think this is not enough information to judge if this is the right approach. Why do you want to start the search after an delay? Maybe because you want to skip the search when the text is changed. So than you need to cancel the currently running coroutine. Otherwise it will still execute the first search
m
getResultFromWebServer
is a name chosen to better explain my request, it's a simple callback that calls a viewmodel function. My doubt was around the debouncing mechanism. Who has that responsability? The viewmodel? Is this ok?
Copy code
class MyViewModel : ViewModel() {
    private val query = MutableStateFlow("")
    fun searchByQuery(query: String) {
        this.query.value = query
    }
    fun observeResult(): Flow<List<String>> {
        return query.debounce(300L).drop(1).map { getResultFromWebServer(it) }
    }
}
@Timo Drick to skip the search when the text changes too fast, yes.
t
This looks good to me. 👍
m
Thank you guys 😊
k
Can you point me to a detailed example of this or a blog post explaining how to use launched effect. I want have similar behaviour integrated with paginated items
m
@Kshitij Patil LaunchedEffect launches a coroutine tied with the composition. when the subjects (the objects you pass to the effect) change or you remove it from the composition (with an if/else) the coroutine is cancelled.
Copy code
// query is the subject of the effect
LaunchedEffect(query) {
    // the coroutine is delayed by 400ms
    // if in the meantime query changes
    // the coroutine is cancelled and callToTheServer is never invoked
    delay(400) 
    callToTheServer(query)
}
k
Got it, thanks for the explanation 🙂
👍 1