https://kotlinlang.org logo
#orbit-mvi
Title
# orbit-mvi
s

Simon

09/01/2021, 3:00 PM
Hi! I am quite new to MVI, but your library looks very promising 🙂 I started looking into the orbit-sample-stocklist-jetpack-compose and how flow is used there for the request of the stocks. In the example the flows live as long as the ViewModel does. What would be the intended way of managing those flows with Orbit in case I need to close and open it again (e.g. with different parameters if I would have some kind of filter functionality). I already found this question in the github repo: https://github.com/orbit-mvi/orbit-mvi/issues/12 As far as I understand the suggestion there is to create coroutineScopes and cancel the previous Job if a new subscription is required. This works, but is there any better way in the meantime or is this still as intended?
a

appmattus

09/02/2021, 12:32 AM
Hi @Simon, one thing that comes to mind is to represent the current state of the filter as a flow and use `mapLatest`; this will manage the coroutine job and cancellation for you.
Copy code
filterFlow.mapLatest { filter ->
    getResultFlowBasedOnFilter(filter)
        .collect {
            ...
        }
}
filterFlow
could simply be a
MutableStateFlow
@Mikolaj Leszczynski anything else come to mind?
✍️ 1
m

Mikolaj Leszczynski

09/02/2021, 8:31 AM
yeah
mapLatest
is a nice idea for a filter implementation! I’d use a
Channel
to keep the separation.
Copy code
override val container = container(initialState) {
    setupFilter()
}

private val filterChannel = channel(Channel.BUFFERED)

private val setupFilter() = intent {
    filterChannel.receiveAsFlow()
        .mapLatest { filter ->
            getResultFlowBasedOnFilter(filter)
        }
        .collect {
            ...
        }
}

fun filter(filter: String) = intent {
    filterChannel.send(filter)
}
alternatively, you could store a
Job
in your state to enable later cancellation of a
Flow
there are quite a few ways to do this and our library is pretty non-restrictive 🙂
s

Simon

09/02/2021, 8:45 AM
Thanks a lot for your quick replies! 😊 I understood that there is no "right" solution for this (maybe that's why you intentionally do not have this as an example in the app? 😉). I just wanted to ask if I am missing something here. My first try was also using a Job as in the linked question, I could try to store that also in the State as you suggested. But I also like the other ideas... I will make up my mind on how I want to proceed here K
👍 1
a

appmattus

09/02/2021, 3:12 PM
also, to save yourself from any pain collecting infinite flows if you use espresso tests... set registerIdling...
intent(registerIdling = false) { ... }
. to be fair we need to create a lint rule around this if we can get some sort of detection working as its not obvious
4 Views