Hey, any idea why would a `.collect {}` call of a ...
# coroutines
f
Hey, any idea why would a
.collect {}
call of a
MutableStateFlow
not work after the initial value? Basically, I create a
MutableStateFlow
in one place and call
emit
(multiple times) there, and at the same time call
.collect {}
in another place, and the callback of
collect
is not executed, except for the initial value. I can clearly see the state of the
Flow
is changing, but
collect
is just not working. I'm also absolutely sure the
collect
call is not getting canceled, as I have tried catching
CancellationException
. The context is a Jetpack Compose app, maybe it's some bug there? SOLVED: the problem was emitting the same list to the StateFlow. Even though the list is changing, its reference has not, and coroutines treat it as the same value, and concludes no new value needs to be emitted. Hence
collect
callback is not called after the initial value.
a
Is there any reason not to use
mutableStateFlow.value = newValue
instead of
emit()
?
u
Maybe your dispatcher is busy. Hard to guess without any code. Is there any runBlocking involved?
f
I want to listen to changes in the StateFlow to update UI accordingly. .collectAsState() doesn't work because.collect{} doesn't work
There is no runBlocking
a
emit()
is a suspend function and it needs dispatching so there may be some timing issues. That's why I asked you why you are using the suspend function to update the value.
f
Ok, i'm gonna try
.value =
Same result
ohhhh I have a guess
Copy code
Values in state flow are conflated using Any.equals comparison in a similar way to distinctUntilChanged operator. It is used to conflate incoming updates to value in MutableStateFlow and to suppress emission of the values to collectors when new value is equal to the previously emitted one.
so if I have a mutable list that changes, and is being assigned to the StateFlow on every change, since its still referentially equal it wont update
u
True.
f
Is there a way to change this behavior to use a different equality?
actually, that won't be needed since in most cases the list won't be referentially equal. In this case I would just copy the list
Yep, it is solved. Thanks for responding
a
Using
MutableList
as state is suspicious and error-prone. You should always use immutable
List
as state.
f
yes i understand that now