Novo Dimaporo
03/30/2025, 7:33 AMprivate val loadTrigger = MutableSharedFlow<Long>()
private var tState = TransactionsState()
@OptIn(ExperimentalCoroutinesApi::class)
val transactionsState = combine(
currentUser.filterNotNull(),
loadTrigger.onStart { emit(0) }
) { user, delayDuration -> user to delayDuration }
.filterNot { tState.isLoading }
.onEach { tState = tState.copy(loadingPage = tState.page + 1, isLoading = true) }
.flatMapLatest { (user, delayDuration) ->
delay(delayDuration)
observeTransactionDetails(
count = tState.loadingPage * PAGE_SIZE,
userId = user.uid,
accountId = accountId)
}
.map { result ->
tState.copy(
transactions = TransactionProcessor
.toListItems(result),
page = tState.loadingPage,
isEndOfList = result.isEmpty(),
isLoading = false
)
}
.onEach { tState = it }
.stateIn(
scope = viewModelScope,
started = SharingStarted.Eagerly,
initialValue = TransactionsState()
)
fun loadNext() {
viewModelScope.launch { loadTrigger.emit(500) }
}
I tried using runningFold at first, but I need to have access to the current state to debounce the request to load more if it is still loading a page.
I did not use paging 3 because I am working on a KMM project.
Let me know if you need more context to understand this snippet.Chrimaeon
03/30/2025, 10:22 AMUjjwal Sai
03/30/2025, 5:28 PMFlow
quite well, but relying on tState
as a mutable variable outside the flow chain can lead to subtle issues — especially with rapid emissions or concurrency.
A more idiomatic approach would be to keep state within the flow itself, using something like runningFold
or scan
, which gives you access to the previous state and emits the new one reactively.
This way, you can handle isLoading
, page
, and transactions
updates in a clean, reactive way without needing to manually track tState
.Novo Dimaporo
03/31/2025, 2:05 AMisLoading
field of the state because the state is only inside this operator and to the collector, I need isLoading
to block the succeeding request to load more items. I was eyeing if I can use CONFLATED channel.Novo Dimaporo
03/31/2025, 2:15 AMChrimaeon
03/31/2025, 5:49 AMUjjwal Sai
03/31/2025, 5:49 AMNovo Dimaporo
03/31/2025, 6:49 AM