https://kotlinlang.org logo
Title
c

Colton Idle

03/08/2022, 12:43 AM
Still not super comfortable with flows, but Im getting a laggy UI in my android app with the following, and was wondering if anyone had any pointers. Basically I just have a search field and as a user types, I want to search against my api, but I want to make sure to wait 250ms before hitting a network call.
var queryText = MutableStateFlow("")
init {
  viewModelScope.launch {
    myState.queryText.debounce(250).collect {
        search(it)
    }
  }
}

private fun search(term: String) {
  viewModelScope.launch {
    val result = service.searchApiCall(term)
...
Now that I think about it. I probably want my old network calls to be cancelled too. Can anyone point me in the right direction about how I should rethink this?
k

Kamesh Yadav

03/08/2022, 1:55 AM
collectLatest
will cancel the previous call
c

Colton Idle

03/08/2022, 1:57 AM
Do you think I should make fun search a suspend function? or should I keep that viewModelScope.launch inside of search?
k

Kamesh Yadav

03/08/2022, 2:00 AM
It should be suspend function
c

Colton Idle

03/08/2022, 2:01 AM
That was my hunch, but do you know why? It was more of a guess on my part.
k

Kamesh Yadav

03/08/2022, 2:45 AM
ChannelFlowTransformLatest
keeps the job reference for the previous block and only cancels that block, if the function is not suspend then it can not be cancelled, or if use use another launch then you have keep the job reference and cancel it yourself
c

Colton Idle

03/08/2022, 2:48 AM
Oh interesting. TIL. Other than that though it seems like everything else looks pretty good?
Looks like my resulting code will be something like this
init {
  viewModelScope.launch {
    myState.queryText.debounce(250).collectLatest {
        search(it)
    }
  }
}

private suspend fun search(term: String) {
    val result = service.searchApiCall(term)
...
g

gildor

03/08/2022, 3:34 AM
General rule, it’s almost always wrong to have a method which launch top level job and returns immediately
c

Colton Idle

03/08/2022, 9:13 PM
@gildor you're referring to the fact that I had a second viewModelScope.launch right? But yes, after I wrote it out here it was a bit of rubber ducking where that seemed to not make sense.
g

gildor

03/09/2022, 1:47 AM
yep, about method search which launches coroutine and even do not returning Job, but suspend function by default for any business logic is better
💯 1
c

Colton Idle

03/09/2022, 5:28 PM
Thanks for teaching!