0

I have a ViewModel which has the following list as StateFlow

private val _mutableStateTopicItemList = MutableStateFlow<List<TopicItem>>(listOf())
val stateTopicItemList = _mutableStateTopicItemList.asStateFlow()

Now inside my Composable function, I want to get an update whenever there's a change in the value of this above variable stateTopicItemList

TopicItem is my CustomClass.

I want an observable inside my Composable that observes any changes like add/update/delete from the viewModel List variable stateTopicItemList

I tried to use the collectAsState() method to get an update but was unsure how to listen to those updates. See this what I tried.

val listOfTopicsWithState = myViewModel.stateTopicItemList.collectAsState()

What I want to achieve is just that whenever there's a change in the list, I want to store it inside my SharedPreference.

Any help will be really appreciated.

Kishan Solanki
  • 13,761
  • 4
  • 85
  • 82

3 Answers3

1

You can use LaunchedEffect to run some code whenever the state changes:

val listOfTopicsWithState by myViewModel.stateTopicItemList.collectAsState()

LaunchedEffect(listOfTopicsWithState) {
    if(listOfTopicsWithState.isNotEmpty()) {
        // do something
    }
}

That said, It's more common to run that kind of logic within the view-model, and limiting the Composable to UI related code.

levi
  • 23,693
  • 18
  • 59
  • 73
1

You can go with the following approach to do so,

    @HiltViewModel
    class TopicsViewModel @Inject constructor(private val sharedPreferencesDelegate: SharedPreferencesDelegate):ViewModel(){
        private val _mutableStateTopicItemList = MutableStateFlow<List<TopicItem>>(listOf())
        val stateTopicItemList = _mutableStateTopicItemList.asStateFlow()


        init {
            observeTopics()
        }


        private fun observeTopics(){
            stateTopicItemList
                .filter { it.isNotEmpty() }//if you want to save empty as well remove this line
                .onEach {it:List<TopicItem>-> sharedPreferencesDelegate.saveTopics(it) }
                .launchIn(viewModelScope)
        }
    }
  

This is the minimal MVVM clean architecture approach to do it the right way. Doing the shared pref access in the composable i.e. UI itself is not the ideal way to.

rahat
  • 1,840
  • 11
  • 24
-1

User MutableStateList instead of Flow in ViewModel

val stateTopicItemList = mutableStateListOf<TopicItem>()

And in your composable function use it like this:

val listOfTopicsWithState by remember { myViewModel.stateTopicItemList }
Abdullah Javed
  • 459
  • 3
  • 17