0

I am following this code to do some error validation. Here's the combineLatest implementation which accepts inputs from 3 fields and does error validation on each of them.

Flowable.combineLatest(
            _emailChangeObservable,
            _passwordChangeObservable,
            _numberChangeObservable,
            (newEmail, newPassword, newNumber) -> {
              boolean emailValid = !isEmpty(newEmail) && EMAIL_ADDRESS.matcher(newEmail).matches();
              if (!emailValid) {
                _email.setError("Invalid Email!");
              }

              boolean passValid = !isEmpty(newPassword) && newPassword.length() > 8;
              if (!passValid) {
                _password.setError("Invalid Password!");
              }

              boolean numValid = !isEmpty(newNumber);
              if (numValid) {
                int num = Integer.parseInt(newNumber.toString());
                numValid = num > 0 && num <= 100;
              }
              if (!numValid) {
                _number.setError("Invalid Number!");
              }

              return emailValid && passValid && numValid;
            })
        .subscribe(_disposableObserver);

My problem is that the combiner function is not triggered unless all 3 input field observables have emitted at least once. So when users enter an incorrect email address, they are not notified until they have entered some data in all the 3 fields.

dev
  • 11,071
  • 22
  • 74
  • 122
  • did you just tried to run RxJava-Android-Samples code? or write a new code based on that? – yosriz Jul 05 '17 at 19:40
  • I am using the same code for learning. No modifications. If you see the linked code, if I remove the skip(1) calls from the Flowables, then I can get error notifications as I want - but there are error notifications as soon as I launch the fragment (without any user input). – dev Jul 05 '17 at 19:48

1 Answers1

3

combineLatest() must have all values for starting emitting something, as by definition the combiner function gets n values that emitted from n sources.

When RxBInding wraps TextView events with RxTextView, it emits an initial value (contents of the TextView) when subscribed, so without the skip(1), you will have your desired logic, the thing is the validation logic in this sample do not expect that, and display error for empty values (by the !isEmpty(newXXX) checks).
My hunch based on the explicit skip(1) transformation is that in this example this is the desired behavior - meaning just when all fields has been entered we need to display errors.

In your case if you want to implement your logic, you need to skip empty values from displaying errors while still emit false at the end as the whole input is not yet valid, then - with any change at any fields independent of the others, while not empty you will the errors .

yosriz
  • 10,147
  • 2
  • 24
  • 38