Home > front end >  How to update data with SharedFlow in Android
How to update data with SharedFlow in Android

Time:10-06

In my application I want update data with SharedFlow and my application architecture is MVI .
I write below code, but just update one of data!
I have 2 spinners and this spinners data fill in viewmodel.
ViewModel code :

class MyViewModel @Inject constructor(private val repository: DetailRepository) : ViewModel() {

    private val _state = MutableStateFlow<MyState>(MyState.Idle)
    val state: StateFlow<MyState> get() = _state

    fun handleIntent(intent: MyIntent) {
        when (intent) {
            is MyIntent.CategoriesList -> fetchingCategoriesList()
            is MyIntent.PriorityList -> fetchingPrioritiesList()
        }
    }

    private fun fetchingCategoriesList() {
        val data = mutableListOf(Car, Animal, Color, Food)
        _state.value = DetailState.CategoriesData(data)
    }

    private fun fetchingPrioritiesList() {
        val data = mutableListOf(Low, Normal, High)
        _state.value = DetailState.PriorityData(data)
    }
}

With below codes I filled spinners in fragment :

     lifecycleScope.launch {
                //Send
                viewModel.handleIntent(MyIntent.CategoriesList)
                viewModel.handleIntent(MyIntent.PriorityList)
                //Get
                viewModel.state.collect { state ->
                    when (state) {
                        is DetailState.Idle -> {}
                        is DetailState.CategoriesData -> {
                            categoriesList.addAll(state.categoriesData)
                            categorySpinner.setupListWithAdapter(state.categoriesData) { itItem ->
                                category = itItem
                            }
                            Log.e("DetailLog","1")
                        }
                        is DetailState.PriorityData -> {
                            prioritiesList.addAll(state.prioritiesData)
                            prioritySpinner.setupListWithAdapter(state.prioritiesData) { itItem ->
                                priority = itItem
                            }
                            Log.e("DetailLog","2")
                        }
}

When run application not show me number 1 in logcat, just show number 2.
Not call this line : is DetailState.CategoriesData

But when comment this line viewModel.handleIntent(MyIntent.PriorityList) show me number 1 in logcat!

Why when use this code viewModel.handleIntent(MyIntent.CategoriesList) viewModel.handleIntent(MyIntent.PriorityList) not show number 1 and 2 in logcat ?

CodePudding user response:

The problem is that a StateFlow is conflated, meaning if you rapidly change its value faster than collectors can collect it, old values are dropped without ever being collected. Therefore, StateFlow is not suited for an event-like system like this. After all, it’s in the name that it is for states rather than events.

It’s hard to suggest an alternative because your current code looks like you shouldn’t be using Flows at all. You could simply call a function that synchronously returns data that you use synchronously. I don’t know if your current code is a stepping stone towards something more complicated that really would be suitable for flows.

  • Related