RxKotlin: Login Screen

Ahmed Rizwan
AndroidPub
Published in
4 min readNov 5, 2017

--

Rx is powerful because we can compose transformations. What that means is that we can have reusable, safe and more functional code that simply plugs into your code.

As an example let’s say we’re making a login screen with an email and a password…

Consider the following rules that we want for our email addresses

Length should be greater than 6

Should have a correct email pattern

Let the user know if any of the above fails

On each key stroke, verify

This is what my code should look like

emailObservable
-> lengthGreaterThanSix
-> verifyEmailPattern
-> retryIfSomethingFails
subscribe()

Simple enough, right?

Similarly for passwords, we’d want

passwordObservable
-> lengthGreaterThanSix
-> retryIfSomethingFails
subscribe()

Both fields have lengthGreaterThanSix common, so let’s create an ObservableTransformer. ObservableTransformers allows composable set of transformations that we can apply on a given observable.

Here we specify transformer’s inputStream & outStream as String. Trim the input String — filter and check if the length is greater than 6 — If not then intercept exception and throw a custom one (i.e. if previously no exception was already thrown in the chain). SingleOrError converts the Observable to a Single, so we convert it back to an Observable.

Similarly write a transformer for email pattern verification.

Here again, we trim, filter to check if the pattern matches, throw an error if it doesn’t match, and intercept to throw a custom exception instead.

Time to test these two transformations, first the character length check

using timber to log messages here

Now a test for email verification, first invalid email “abcabcabc”

And for correct email “name@domain.com”

So far so good!

Connecting things with a UI

Let’s say I have this screen

what the UI looks like…

For brevity, I’m gonna use RxBindings!

When I run this code, in the editText if I go beyond 6 letters, it gives me this weird exception.

onError: Sequence contains more than one element!

So what exactly is different when I use EditText onTextChange with my observables? In both cases I’m doing the same thing, right?

[Narrator: He wasn’t doing the same thing.]

Actually the difference is that the one with the editText is an infinite stream.

To actually explain it, streams will do the trick…

Observable.just("abc")

This produces the following stream

| — — — “abc” —→ (end)

RxTextView.afterTextChangeEvents(editTextEmail)

If I type in abc, it produces the following stream

| — — — “a” — “ab” — “abc” — →

Comparing the two streams, you can see that the first one produces only one item, and the second one emits three, hence the above code fails.

In order to fix this, we’d use flatMap with nested observables to handle each individual string inputs separately

use flatmap and an internal Observable

Now if we type in abc, we’d have three observables on the stream, doing their own verification and error handling. In the end, it’ll just be one observable.

| —Obs(“a”)—Obs( “ab”) — Obs(“abc”)→

After doing the same for lengthGreaterThanSix and adding a debounce operator, the output would be like

Final code

That’s it for now!

Happy coding!

Some good sources for learning about Rx:

Dan Lew’s Common RxJava Mistakes

RxMarbles

Official Site

--

--

Ahmed Rizwan
AndroidPub

Web | Android | Senior Software Engineer @QuixelTools