How update state with copy function

40 Views Asked by At

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

1

There are 1 best solutions below

0
Mukesh Kumar On BEST ANSWER

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)
    }
}