gts13
04/28/2021, 3:00 PMdata class ViewItem(
val id: String,
val title: String,
var description: String = "" // yes a var
)
private val _items: MutableStateFlow<List<ViewItem>> = MutableStateFlow(emptyList())
val metrics: StateFlow<List<ViewItem>> = _metrics
_metrics.value = _metrics.value.toMutableList().find { // some predicate }?.description = "a new title"
The _metrics
won’t emit the new value (which is actually a change in the ViewItem
object.
Am I right or I am missing something here?
And If I am right, in order to solve the above “issue” I need to use Channel
or is there any other way with StateFlow
?Casey Brooks
04/28/2021, 3:07 PMval currentList = _metrics.value.toMutableList()
currentList.find { it.id == "1" }?.description = "a new title"
_metrics.value = currentList
Francesc
04/28/2021, 3:08 PMMutableStateFlow
is not aware to changes to your list. To trigger a new emission you have to make a new copy of your state with the list updated instead.gts13
04/28/2021, 3:10 PMval tempList = _metrics.value.toMutableList()
tempList.find{ // }...
_metrics.value = tempList
@Francesc like this? Becaause doesnt work. Or could you please tell me how?Casey Brooks
04/28/2021, 3:14 PMAny.equals
. If the result of your modifications changes the equality property of the list, then it should be emitted. A List is equal to another List when it contains the same contents in the same order. So to get a “different” list, you either need to add an item, remove an item, or cause one item to become not equal to a previous one.
However, mutable properties are very problematic for things like this. When you modify a ViewItem
, it gets the new value in both the new and old lists. Even though the values of the objects are now different than they were, the two lists are still equal because they share the same instance of ViewItem
. This is likely your problem.copy
it to receive a new instance that is not shared between the two lists.copy
method to make changes, as it forces you to do this correctlygts13
04/28/2021, 3:23 PMCasey Brooks
04/28/2021, 3:30 PMSharedFlow
also does not conflate emissions like the StateFlow
does, but also like the Channel it does not really hold onto a value. Its “replayCache” kinda does, but it doesn’t hold the strong guarantee that a StateFlow does, so you’d have to assume the “current value” could be null.