1

I'm using a MutableMap to save the data which is updates every 5 seconds and I expect also to be updated the UI showing part of the Map. After trying different solution I found that if I add another Double variable both Map and Double are updated on the UI but if I keep only Map variable nothing changes:

ViewModel Variables:

private val _stockRealPriceFlow = MutableStateFlow<MutableMap<String, Double>>(mutableMapOf())
val stockRealPriceFlow: StateFlow<MutableMap<String, Double>> = _stockRealPriceFlow.asStateFlow()

private val _draftPrice = MutableLiveData<Double>()
val draftPrice: LiveData<Double> = _draftPrice

ViewModel Variables Update:

_stockRealPriceFlow.value[it.name] = it.currentPrice()
_draftPrice.value = stockRealPriceFlow["Draft"] ?: 0.0

Activity:

val stockRealPriceFlow by viewModel.stockRealPriceFlow.collectAsState()
val draftPrice by viewModel.draftPrice .observeAsState(0.0)

Column(
    modifier = Modifier
        .padding(8.dp)
) {
    Text(text = stockRealPriceFlow["Draft"].toString())
    Text(text = draftPrice.toString())
}

How that can be explained if the MutableMap variable is same in both cases? What is the correct way of working with the map on this case?

I expect UI always show the Map values.

1
  • stockRealPriceFlow will only update if the new value is different from the previous value in the StateFlow Commented May 3, 2024 at 14:34

1 Answer 1

6

The StateFlow doesn't provide a new value, that's why your UI won't update. Instead, the same MutableMap is updated with new/changed values. That won't trigger a new value for the flow, though.

The solution is to never expose mutable values in your view model:

private val _stockRealPriceFlow = MutableStateFlow<Map<String, Double>>(emptyMap())
val stockRealPriceFlow: StateFlow<Map<String, Double>> =
    _stockRealPriceFlow.asStateFlow()

To update the map of the mutable flow you need to replace the map with a new one that contains the updated element. Instead of setting _stockRealPriceFlow.value[it.name] = it.currentPrice() you should use this:

_stockRealPriceFlow.update { oldMap->
    oldMap + (it.name to it.currentPrice())
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.