0

I have a login screen with an Observable which emits items when email and password are valid, and then, I subscribe enabling or disabling the login button.
Now, I want a way to avoid multiple clicks in the login button (avoiding multiple calls to webservice and opening multiple activities after login).

I have tried to use doOnNext() to disable the button but it conflicts with my validation (I ended up enabling the button without being possible)

my code:

InitialValueObservable<CharSequence> emailChangeObservable = RxTextView.textChanges(binding.tietLoginLogin);
InitialValueObservable<CharSequence> passwordChangeObservable = RxTextView.textChanges(binding.tietLoginPassword);

Observable<Boolean> infoValidStream = Observable.combineLatest(emailChangeObservable, passwordChangeObservable, (email, password) -> {
            boolean validEmail = email.length() > 3 && email.toString().contains("@");
            boolean validPass = password.length() > 1;
            return validEmail && validPass;
        });

        infoValidStream.subscribe(validEmailAndPass -> binding.btLoginSignIn.setEnabled(validEmailAndPass));

        RxView.clicks(binding.btLoginSignIn)
              .subscribe(o -> login()); // do the request to the webservice and return a Single<User> if success.

How can I achieve this behavior?

reinaldomoreira
  • 5,388
  • 3
  • 14
  • 29

2 Answers2

0

You should use the debouce method. It will make your observable not emit new items unless a span of time has passed. You can set this time span accordingly to your needs.

Take a look here to see the complete explanation.

You can use debounce is your code in this way:

RxView.clicks(binding.btLoginSignIn)
              .debounce(400, TimeUnit.MILLISECONDS)
              .subscribe(o -> login());

This will avoid the user start the connection multiple times in a second.

Edit:

But you can also use a filter:

RxView.clicks(binding.btLoginSignIn)
              .filter { !connection.isActive() }
              .subscribe {login()};

It is written in Kotlin, sorry I am a bit rust in Java, but that's the logic. You will need some method to know if the connection is still active.

Happy coding!

Leandro Borges Ferreira
  • 12,422
  • 10
  • 53
  • 73
  • thanks, but the connection may be fast or slow, how can I make sure when the user clicks again, it will work for him? – reinaldomoreira Jan 16 '18 at 19:38
  • The idea it is just to prevent the user to start the connection multiple times. If you want the user to just be able to connect if no other connection is active, you should use filter. – Leandro Borges Ferreira Jan 16 '18 at 19:48
-1

Use the take operator e.g.

RxView.clicks(binding.btLoginSignIn)
      .take(1)
      .subscribe(o -> login());
JohnWowUs
  • 3,053
  • 1
  • 13
  • 20