Search code examples
androidkotlinmutablestateof

How update state with copy function


My Ui state

data class LoginUiState(
    val loginModel: LoginModel = LoginModel(),
) : UiState

My ViewModel

@HiltViewModel
class LoginViewModel @Inject constructor() : BaseViewModel<LoginUiState>() {

    override fun handleUiEvent(uiEvent: UiEvent) {
        when (uiEvent) {
            is LoginUiEvent.LoadScreenData -> {
                loadScreenData()
            }

            is LoginUiEvent.OnClickLogin -> {
                onClickLogin()
            }
        }
    }

    private fun loadScreenData() {
        updateState { currentState ->
            currentState.value = LoginUiState(LoginModel("login", "password"))
        }
    }

    private fun onClickLogin() {
        updateState { currentState ->
            currentState.value = currentState.value?.copy(loginModel = LoginModel(login = "d"))
        }
    }
}

My BaseViewModel

abstract class BaseViewModel<S : UiState> : ViewModel() {
    private var _uiState = mutableStateOf<S?>(null)
    val uiState: State<S?> = _uiState

    abstract fun handleUiEvent(uiEvent: UiEvent)

    fun updateState(block: (state: MutableState<S?>) -> Unit) {
        block.invoke(_uiState)
    }
}

How update only field "login" in loginModel, but without change field: "password". My function "onClickLogin" not good work, because I don't how make it


Solution

  • You can modify the onClickLogin function in your LoginViewModel. You will need to access the current state, modify only the login field, and keep the password field unchanged

    private fun onClickLogin() {
    
        updateState { currentState ->
    
            val currentLoginModel = currentState.value?.loginModel
    
            val updatedLoginModel = currentLoginModel?.copy(login = "d")
    
            currentState.value = currentState.value?.copy(loginModel = updatedLoginModel)
        }
    }