Home > Software design >  How can I initialize a val that need to be initialize through viewModelScope?
How can I initialize a val that need to be initialize through viewModelScope?

Time:01-22

I have the below code

class MainViewModel(private val todoDao: TodoDao) : ViewModel() {
    private var todoList = mutableStateListOf<TodoItem>()
    private val _todoListFlow = MutableStateFlow(todoList)

    val todoListFlow: StateFlow<List<TodoItem>> get() = _todoListFlow
    private var postExecute: (() -> Unit)? = null

    init {
        loadTodoList()
    }

    private fun loadTodoList() {
        viewModelScope.launch {
            todoDao.getAll().collect {
                todoList = it.toMutableStateList()
                _todoListFlow.value = todoList
                postExecute?.invoke()
            }
        }
    }
}

You notice the var todoList is var.

Since it get initialize only once, I hope to make it val. How is that possible, given it is initialized in the viewModelScope?

CodePudding user response:

It is unclear why you are using a mixture of MutableStateFlow and SnapshotStateList to end up with MutableStateFlow<SnapshotStateList<TodoItem>> when there is really no need for the _todoListFlow, but to answer your question simply initialise the SnapshotStateList then upon collection modify the data structure contents :

class MainViewModel(private val todoDao: TodoDao) : ViewModel() {
    private val todoList = mutableStateListOf<TodoItem>()
    private val _todoListFlow = MutableStateFlow(todoList)

    val todoListFlow: StateFlow<List<TodoItem>> get() = _todoListFlow
    private var postExecute: (() -> Unit)? = null

    init {
        loadTodoList()
    }

    private fun loadTodoList() {
        viewModelScope.launch {
            todoDao.getAll().collect {
                todoList.clear() // optional if getAll has multiple emissions?
                todoList.addAll(it)
                _todoListFlow.value = todoList
                postExecute?.invoke()
            }
        }
    }
}
  • Related