Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MutableStateFlow not working with MutableList

Here is my MutableStateFlow value I try to work with:

val songList: MutableStateFlow<MutableList<Song>> = MutableStateFlow(arrayListOf())

I need to observe changes (after methods like add, removeAt etc.) on my MutableList above but can't achieve that. My guess is since only the elements of the list change instead of the list itself, collect method doesn't get fired.

How can I achieve that using StateFlow if possible? If not, what is the correct way to do it?

Note that I need initial value of arrayListOf(), so LiveData probably won't be enough for me.

like image 387
bugra Avatar asked Jul 29 '26 12:07

bugra


2 Answers

In your view model:

val songList: MutableStateFlow<MutableList<Song>> = MutableStateFlow(emptyList()) // modified

fun add(song: Song) {
    songList.update {
        songList.value.toMutableList().apply { this.add(song) }
    }
}

in a composable:

val songs = yourViewModel.songList.collectAsStateWithLifecycle()
like image 61
fr1550n Avatar answered Jul 31 '26 03:07

fr1550n


  • Helpful reading: Notify LiveData observers when nested properties change

  • What is the issue:

    • StateFlow and LiveData won't get notified if the nested field gets changed.

    • Ex 1: Update specific item of a List (not add/remove).

    • Ex 2: Update specifc property of an object.


Solution:

  1. Create helper extension function:

    fun <T> List<T>.mapButReplace(targetItem: T, newItem: T) = map {
        if (it == targetItem) {
            newItem
        } else {
            it
        }
    }
    
  2. React on action (ex: click event):

     val newStudent = student.copy(isSelected = !student.isSelected)
    
     viewModel.updateStudents(student, newStudent)
    
  3. Handle in ViewModel:

     fun updateStudents(currentStudent: Student, newStudent: Student) {
         val newList = _students.value.mapButReplace(currentStudent, newStudent)
    
         _students.value = newList
     }
    
like image 35
Sam Chen Avatar answered Jul 31 '26 04:07

Sam Chen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!