I am creating a `MutableState` in this way: ```var...
# compose
a
I am creating a
MutableState
in this way:
Copy code
var result by mutableStateOf<R?>(value = null, policy = neverEqualPolicy())
Now I am setting an
object
via
result = TheObject
I am listening to that via
Copy code
LaunchedEffect(Unit) {
  snapshotFlow { result }.collectLatest {
    (logging here)
  }
}
But I am only receiving a log when the first object is set, all subsequent value changes with
TheObject
on
result
are not logged. Shouldn’t
neverEqualPolicy()
ensure that every value change is emitted? What am I missing here?
s
snapshotFlow
itself seems to be doing a .equals check of its own to know whether to emit or not, despite whatever equality policy you’ve setup to the mutableState itself. At least that’s my interpretation of the docs here
Probably this piece of code here is what prevents this emission
👍 1
a
That is very unfortunate, thanks @Stylianos Gakis
Would be a nice touch if we could set a
policy
on
snapshotFlow
too. I guess that would be a feature request then.
s
Maybe you can copy paste the source code of snapshotflow and make your own alternative while adjusting the code to your liking for the time being.
a
Yes, that is a good option, I also thought of wrapping every emission in a Wrapper class that is always
!=
anything else and pass the check in
snapshotFlow
then unwrapping it for the collector, maybe I can create a top level method for this without copying
snapshotFlow
s
Yeah give both options a try and please do tell if one works for you, I’d be curious to know 🙌
👍 1
z
This is code smell. State is idempotent by definition. Trying to emit the same state multiple times usually indicates you're not actually dealing with state, but events.
a
Yeah we are building something to handle events, right now my usecase is receiving a screen dismissal event, which does not hold any data and thus could be an object. I might just override the equals and return false always, or maybe make it a data class with a random id, so we could still identify the same event.
z
You shouldn't be sending events through MutableStates - those are for states. And snapshotFlow is for reading state objects, which is why it also conflates. If you need to send events around, you should be using something like MutableSharedFlow.
a
This is true up to a point. A problem arises, if you have to propagate events across receivers that have a state, such as Fragments or Composables managed by a backstack. In those cases the event might be sent when there is no receiver yet and needs to be picked up as soon as the receiver is available so as not to get lost. A SharedFlow would send the event to nowhere if there is no receiver yet. So for cases like these, the solution tends to be a bit more subtle. Thanks for pointing my mind back to the basics though, what you are saying is of course true for 90% of events, just not in this specific case I would say.
s
Maybe then you want to model your events as state which needs someone to acknowledge it, handle it, and then report back after it has successfully handled it in order to clear the state. Something like what’s suggested here. Using MutableState changes as events does in fact sound like something you don’t want to do.
1
a
I think this might be the best option