I have a simple Todo Compose View as ```class App...
# compose
e
I have a simple Todo Compose View as
Copy code
class AppViewModel : ViewModel() {
    private var todoList = listOf(
        TodoItem(0, "My First Task"),
        TodoItem(1, "My Second Task", true)
    )
    private val _todoListFlow = MutableStateFlow(todoList)

    val todoListFlow: StateFlow<List<TodoItem>> get() = _todoListFlow

    fun setUrgent(index: Int, value: Boolean) {
        val modified = todoList.toMutableList()
        modified[index] = modified[index].copy(urgent = value)
        todoList = modified
        _todoListFlow.value = modified
    }
}

val viewModel = AppViewModel()

@Composable
fun MyTodoList {
    val todoListState = viewModel.todoListFlow.collectAsState()

   LazyColumn(modifier = Modifier.fillMaxHeight()) {
        items(items = todoListState.value, itemContent = { item ->
            Row {
                Text(text = item.title)
                Checkbox(
                    checked = item.urgent,
                    onCheckedChange = {
                        val index = todoListState.value.indexOf(item)
                        viewModel.setUrgent(index, it)
                    }
                )
            }
        })
    }
}
But I dislike to update a field in the list, I have to create a modify list to pass to the stateFlow.
Copy code
fun setUrgent(index: Int, value: Boolean) {
        val modified = todoList.toMutableList()
        modified[index] = modified[index].copy(urgent = value)
        todoList = modified
        _todoListFlow.value = modified
    }
I can fix it using Solution in https://stackoverflow.com/a/75004437/3286489, but feel it is wrong, as that solution is having MutableState in ViewModel. I wonder how can I avoid the need to create the entire list to send through the StateFlow, if I just need to change a variable that update the compose view?
🧵 3
z
I’ve never directly tried to change a List. Have you considered using a reactive database such as Room and instead just update the entry in your database? Room will then emit the updated todo list
m
I can fix it using Solution in
That does not appear to be a solution to your problem. Your "problem" is:
I dislike to update a field in the list, I have to create a modify list to pass to the stateFlow
That seems to be what
SnapshotStateList
does (see its
mutate()
function), and
SnapshotStateList
is what backs
mutableStateListOf()
. If your sole concern is that you feel that the code for updating an immutable list is ugly, implement an extension function that hides the ugly bits.