Colton Idle
12/23/2022, 3:05 PM@HiltViewModel
class MyViewModel @Inject constructor(val appState: AppStateHolder) : ViewModel() {
val searchText = MutableStateFlow("")
init { viewModelScope.launch { searchText.debounce(1000).collectLatest { doSearch(it) } } }
fun updateSearchText(text: String) { searchText.update { text } }
fun doSearch() {...}
}
BasicTextField(value = searchText, onValueChange = { viewModel.updateSearchText(it) } ...
Guilherme Delgado
12/23/2022, 3:23 PMfun <T> debounce(waitMs: Long = 700L, scope: CoroutineScope = CoroutineScope(Dispatchers.Main), action: (T) -> Unit): (T) -> Unit {
var debounceJob: Job? = null
return { param: T ->
debounceJob?.cancel()
debounceJob = scope.launch {
delay(waitMs)
action(param)
}
}
}
val updateDebounce = remember { debounce<Unit> { onFieldsUpdated(...) } }
Same logic If i want throttles:
fun <T> throttleFirst(skipMs: Long = 700L, scope: CoroutineScope = CoroutineScope(Dispatchers.Main), action: (T) -> Unit): (T) -> Unit {
var throttleJob: Job? = null
return { param: T ->
if (throttleJob == null || (throttleJob as Job).isCompleted) {
throttleJob = scope.launch {
action(param)
delay(skipMs)
}
}
}
}
ViewModel:
private val loadThrottle = throttleFirst<Unit>(1000L, scope = viewModelScope) { nextPage() }
fun loadMore() {
loadThrottle(Unit)
}
Guilherme Delgado
12/23/2022, 3:24 PMChris Fillmore
12/23/2022, 10:42 PMursus
12/25/2022, 12:24 AMColton Idle
12/26/2022, 8:46 PMgildor
12/27/2022, 3:36 AMColton Idle
12/27/2022, 2:42 PMColton Idle
12/27/2022, 5:39 PMColton Idle
12/27/2022, 5:39 PMursus
12/27/2022, 5:41 PMColton Idle
12/27/2022, 5:43 PMursus
12/27/2022, 5:44 PMursus
12/27/2022, 5:47 PMstream
.collect {
val foo = it + 5
print(foo)
}
vs
stream
.map { it + 5 }
.collect {
print(it)
}
anyways the issue is this, outout is the same, but the 2nd is correct semanticallyColton Idle
12/27/2022, 5:53 PMChris Fillmore
12/27/2022, 5:56 PMclass MyViewModel : ViewModel() {
val searchValue = MutableStateFlow("")
val results = searchValue
.debounce(1000)
.mapLatest { doSearch(it) }
suspend fun doSearch(query: String): List<Any> {
// Do your search here
return emptyList()
}
}
@Composable
fun MyComposable(myViewModel: MyViewModel = viewModel()) {
val searchQuery by myViewModel.searchValue.collectAsState()
val searchResults by myViewModel.results.collectAsState(initial = emptyList())
TextField(
value = searchQuery,
onValueChange = {
myViewModel.searchValue.value = it
},
)
searchResults.forEach {
// Show results in UI here
}
}
Chris Fillmore
12/27/2022, 5:59 PMdoSearch
just returning List<Any>
but of course this should return your business result typeColton Idle
12/27/2022, 6:33 PMgildor
12/28/2022, 2:18 AM