Guys how do you manage state using flow? I have he...
# android
n
Guys how do you manage state using flow? I have here my code, but I am not confident about this.
Copy code
private 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.
c
@statmark56, @Yves Kalume , @Pavel Haluza and @olanre12waju, your time to shine - help your fellow Android dev. This is a not not kotlin but kotlin colored post now. 😉
lol 1
😅 2
u
You're managing state using
Flow
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
.
🧵 2
🙇‍♂️ 1
n
Hi @Ujjwal Sai thanks for the respond. The problem with sacn or runningfold is that I cant use the
isLoading
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.
🧵 3
Or maybe I will just give-up reactive for now. It is a little hard to handle, and maybe lacks some operator. I used RxJava before and I think my experience was better because of operators like Publish, typeOf, Merge, etc.
🧵 3
c
Please don’t sent your answers to the main channel.
u
Sure
n
oh, sorry. Sure!