I have a view with two fields: one for the email and another for the phone number. I need to validate them by updating a button on the view.
There is the code:
@HiltViewModel
class CreateAccountEnterEmailViewModel @Inject constructor(
appData: AppData,
) : ViewModel() {
private var email by mutableStateOf("")
private var phoneNumber by mutableStateOf("")
private var _isPhoneNumberFieldVisibleState: MutableStateFlow<Boolean> = MutableStateFlow(appData.isPhoneNumberRequiredForRegistrationParam.orDef())
val isPhoneNumberFieldVisible: LiveData<Boolean> = _isPhoneNumberFieldVisibleState.asLiveData()
class PairMediatorLiveData<F, S>(firstLiveData: LiveData<F>, secondLiveData: LiveData<S>) : MediatorLiveData<Pair<F?, S?>>() {
init {
addSource(firstLiveData) { firstLiveDataValue: F -> value = firstLiveDataValue to secondLiveData.value }
addSource(secondLiveData) { secondLiveDataValue: S -> value = firstLiveData.value to secondLiveDataValue }
}
}
private val isEmailValid: LiveData<Boolean> =
snapshotFlow { email }
.map { validateEmail(email = it) }
.asLiveData()
private val isPhoneValid: LiveData<Boolean> =
snapshotFlow { phoneNumber }
.map { validatePhone(phone = it) }
.asLiveData()
val isContinueBtnEnabled: LiveData<Boolean> = PairMediatorLiveData(isEmailValid, isPhoneValid)
.switchMap {
return@switchMap liveData {
emit(it.first ?: false && it.second ?: false)
}
}
fun updateEmail(email: String) {
this.email = email
}
fun updatePhoneNumber(phoneNumber: String) {
this.phoneNumber = phoneNumber
}
The idea is that when the user updates their email or phone number, this update is intercepted by a mediator that provides the appropriate state depending on whether validation has passed or not.
However, for some reason, I see that nothing goes beyond calling the updateEmail or updatePhoneNumber method. What am I doing wrong?
P.S. There is, of course, a subscription in the view to isContinueBtnEnabled.
I took a look at your code and I can surely say that I'm not 100% sure what might be wrong with your logic. Just wanted to mention that.
I see that there is a subscription in the view to
isContinueBtnEnabledbut I believeViewModel's logic for enabling the Continue Button might be flawed. I think theswitchMapblock is not evaluating as expected.The incorrect implementation of the
PairMediatorLiveDataandswitchMaptransformations might be leading to incorrect logic for when we want to enable the Continue Button.Maybe we can simplify the logic by directly observing changes in the email and phone number validity
LiveDataand updating the combined validity state accordingly instead of using a customPairMediatorLiveDataandswitchMap.I tried to simplify the logic and ensure that the combined validity state of email and phone number is correctly reflected in the
isContinueBtnEnabled.Hope that helps or at least can create a good starting point for solving your issue.