Creating Awesome UX with Observables – Feather Knee – React Rally 2019

Creating Awesome UX with Observables – Feather Knee – React Rally 2019


All right. Hi, everybody. So my talk is about creating awesome user
experiences with observables. As he mentioned, my name is Feather Knee and
yes, that is my real name and I’m a senior UI developer at NVIDIA. And you can reach out to me through Twitter. You can also just talk to me, I’m pretty friendly,
so yeah. So my goals today is to impart a conceptual
understanding of observables and streams. Give you some practical applications for those
things, and also, go into some kind of implementation variations. So my motivation for this talk is kind of
twofold. One of them comes from my background as an
artist. So this is actually one of my paintings. It’s a painting of a reflection in a stream,
and this is how I originally saw it, which is upside down. And most people would see this painting and
they’d say, why don’t you put it the right side up? And this is kind of a thing I always enjoyed
as an artist was kind interacting with people and I think this is what’s taken me from flat
paintings to the web is that sense of interaction. I find that really fascinating and one of
the things I love about observables is it gives you this whole other medium to be interactive
with your users. So my other motivation for this talk is I
feel like a lot of really smart people are very put off by the whole concept of observables. They’re just kind of intimidated by it. And I think it can be really intimidating
if you kind of dive into implementation first, but if you think about it just in terms of
kind of the concept of observables, then you kind of slide into implementation. It just makes a lot more sense. So that’s what we’re going to try to do today. So basically — and there’s going to be a
lot of goats, so just know that ahead of time. So basically an observable is when a thing
is watching another thing. It’s really that simple. So I’m going to tell you a story of observables
in the wild. Suppose one day you’re hiking in the Alps,
because that’s just the kind of person you are, you’re hiking in the Alps, and you stop
to eat lunch, you have an apple with you, you give one apple core to one goat and then
you just keep hiking and later on you turn around and there’s 50 goats following you. This actually happened to me one time, by
the way. [laughter]
So this is the formal definition, and don’t get too hung up on that, but kind of what
I want you to know is an observable is kind of a design pattern. It’s been with us for a long time. Design patterns, for those of you who weren’t
doing software in the ’90s is, it’s kind of like a template. It’s a way of doing a thing you do often in
software. Observables is kind of a two-part pattern. You can it’s an observer and a subject. And you can think of the subject as kind of
like a speaker and observer is the ear. Goats are very observant. So what does that have to do with streams? I don’t know who did this to their goat, but
I just love this photo. So a stream can be a lot of things. It could be a series of observations. It could be a series of events. A collection of data points. And so you’re kind of probably wondering now,
like, how are those two things connected? I don’t know how this goat did that, either. So if you think about like movies: So a movie
is kind of like a series of events that happens over time. It’s continuous, whereas if you think about
like a snapshot, it’s just one point in time. So now that we understand streams, let’s begin
to talk a little bit about collections. Oh, actually, sorry. Yeah. Series of events in a UI or a series of data
points. So collections are kind of like arrays. So it’s kind of like a — if you have a thing
that’s observing another thing, it’s collecting all these data points and it just kind of
forms this more loose assortment. So it’s kind of like an array but it’s a little
more informal. But use these array operations with collections. I know you’re probably saying all this is
really cool, Feather, but why are you telling me this? And basically I feel it’s great to have cool
technology, but at the end of the day, it all has to come down to creating awesome user
experiences, especially as frontend developers, I know we love to kind of like immerse ourselves
in the tech, but really for me it’s kind of like get back to that interactivity, that
sense of delight and wonder that we can create in people that are using our stuff. So some of my design goals when I’m kind of
like thinking about implementing something, is sort of making it more simple for people. Fewer steps to complete a process. So I love observables because they give you
these things like actions or there’s no submit button. And that was the first thing that got me about
RxJS where I saw input and you would type in and I remember thinking, where is the submit
button. And I was like, oh, that’s really cool. So I like this kind of like reactive behavior
and it’s actually a whole school of thinking around design called anticipatory design and
there are kind of these user-centric patterns. So you can think of it as user flows without
speed bumps and it’s all going through this sort of smooth transaction. This by the way is goat yoga which I’ve never
tried before, but I love goats and I love yoga, so I feel like it’s calling my name. So a fun fact about anticipatory design is
that it’s also very connected with data science which if any of you saw my talk last year,
you know it’s a thing I’m super passionate about. So as you’re browsing the web kind of like
you’re the subject and the internet is the observer. So let’s talk about the stream types again. So as we mentioned earlier, a stream can be
a series of things that a user is doing with a website. Could be — this is very fluid, like it’s
the things that we typically do, mouse clicks, keystrokes as we just saw earlier, sometimes
the mouse is not available, so it could be other things. I think voice is a fun thing to play with. I love playing with the speech synthesis API. There’s also values, so that’s streaming data. And there’s different types of libraries that
kind of work with these types of observables, so there’s the RxJS is kind of the granddaddy
of them all and then there’s Bacon and Kefir, which makes me really hungry when I think
about it and kind of the value-driven one, and malBecks, and Redux, for three ducks,
but anyway, so streaming data is basically data that arrives as a stream and actually
do any of you work with streaming data on a daily basis? I see like two hands. Yeah, so I think most of us work with like
REST endpoints and we kind of have that familiar experience where you go and you request some
data and you kind of give us a little chunk of data and that’s the transaction, so these
other types of endpoints that you can hit will give you kind of like an on switch where
you’re turning on net flow of data and it’s coming, it’s really like a firehose type of
situation, so it’s a little different. And the same thing happens with events, so
you know, as a user is interacting with whatever website you have, there’s kind of a series
of things that come in, like data points, is that user is moving around and navigating
and those are also streams. And there’s a lot of different ways to deal
with that. Today we’re going to talk a lot about RxJS. But we also have like a surprise guest because
as I was writing this talk, I learned some things about React that I’ll go into later. That I’m just going to tease you a little
bit with right now. So RxJS is a little bit intimidating at first. How many of you have ever played with RxJS
first. I’m just curious, so that was a fair showing. So I don’t know about, you but the first time
I kind of saw all the operators I was like oh, my God, that’s a lot of operators. So if you can — if you think about it sorry,
I make stupid jokes all the time, if you haven’t noticed, so if you think about these operators
in terms of streams, I think it makes a lot more sense. So like if you have a couple streams, a switchMap,
so remember it has that kind of like map-like analogy, a switchMap will take just the latest
stream. A merge map will take all of the streams,
and a conCAT map will take all of the streams but it has to come later. So here are some common uses of these themes. Type ahead search, password verification and
drag and drop. So a type ahead search you probably have all
encountered this a lot of times, it’s basically listening for users’ keystrokes and it will
live update results and usually these results are returned asynchronously. So there’s a couple of things you have to
think about. Like if you have a person who’s kind of typing
and then they type really quickly and then they back space a lot, it’s going to send
out a ton of network requests, so you want to sort of handle that a by debouncing those
network requests, only have a certain number of requests go out of all the things that
they type. You also want to handle like a loading state
because you’re getting your data asynchronously so you know there’s going to be a little bit
of time for that and you want to be able to handle when there’s no results coming back
and it’s possible to do this with just JavaScript. A lot of people have done this, just kind
of straight-up JavaScript. It’s a little bit complicated. It’s totally doable. You have an input. You have handlers to listen for updates, you
have a loading state handler, and you have a debounce mechanism which you can just kind
of roll your own. It does get kind of complicated, however. These are actual goats who live in trees,
by the way. How cool that?? So with RxJS, this is actually really simple. You have your input and up kind of wrap it
in an observable stream, and that switchMap operator that we talked about just takes the
most recent thing, so kind of everything that’s not usable anymore, it throws it out and it
has all of these built-in operators for dealing with debouncing, which are very nice and loading
states. So I’m just going to show you a kind of a
little demo of this that I wrote, and this is searching the GitHub API and it’s only
looking for images, because I just care about images, and it has like a pretty simple loading
state, it doesn’t really handle no results, so it’s very simple. So first the first thing I did was you know,
just look up myself. And I also wrote like a weird loading state. So yeah, that’s me, right? Actually, that’s not me. There I am. That’s me! That is actually me. But you can see, I didn’t actually handle
no results, so you can just see the network kind of turning red there in the network tab. This is a recording, by the way, I wasn’t
going to do this live, I mean I’m not crazy. But anyway. So you can see the switchMap there working. It’s just kind of taking the latest of whatever
is being piped in. And when you look at kind of like RxJS in
action, you see all these things that look very stream-like, like pipes and tap and — it
all makes a lot of sense when you kind of understand the stream part. So yeah, there’s the pipe. And this actually — this code snippet here,
all of it is using recompose, with React, and so our codebase at work relies pretty
heavily on recompose and I remember kind of learning about Hooks and thinking, oh, I don’t
think recompose is going to be a thing much longer and it turns out I was kind of right
about that. So I got to thinking, what about Hooks? And realized that I could kind of like do
a lot of what I was doing already with RxJS, just using Hooks and not using recompose. So you can — there’s a lot of options here. You can just kind of like use your own, use
observables, Hooks, that integration is actually pretty simple. You can also use this, there’s an open source
library called RxJS Hooks that’s pretty fun and I feel like that kind of makes it a lot
more accessible if you’re just getting your feet wet. So I decided to build another demo. This time I’m searching the xkcd API. How many of you know this cartoon, yes, we’re
nerds, we all know this. Only responds one time, images, my little
rainbow roller thingy, and the xkcd design is just numbers. So you just type in numbers and a random cartoon
comes up. So it’s pretty similar, different API and
different technology. The code itself is very different so we’re
going to dive into that and actually when I first started writing this, I thought, I’m
just going to use RxJS with kind of like a Hooks situation. And I started writing it, and then like a
few hours later, I realized, I don’t really need Hooks, I mean I don’t really need RxJS,
I can just use Hooks, so I did that, and it mostly worked out pretty well. So you have this kind of observable built
into Hooks cause the use effect and here we have useEffect that is that input parameter
that someone types in. The hard part for me was the debounce part. It took me a lot time for that to work. And that’s because I decided to roll my own
rebounds, which is probably pretty silly but it works pretty well. You could use maybe like a LoDash debounce. I really like the RxJS one, it’s super-nice. Mine is not as nice, but whatever, it worked,
so — So I just decided to go ahead and keep rolling
with this experiment and try a password-checking input, and we had a component like this at
work, where we used RxJS and Recompose, so it was kind of a similar pattern, so you had
just like an input where it was listening for user inputs and giving the user positive
feedback as they were typing, so as they met all of the conditions for a password, it would
just kind of say, doing good, yeah, keep going, yeah, right length, yeah, you got numbers
and letters in there. It was kind of a nice pattern. I know earlier in the web we were all about
error messages, but I liked the positive feedback, so maybe I’m just like a hippie, but whatever. I realized after the last talk it’s really
not even visible if you’re colorblind. But my bad. [laughter]
So there’s basically a list of all of your conditions, and your submit button is — it’s
disabled until all the conditions are met. And so that actually works pretty well. And so again, with RxJS, we — when — in
my work application that we wrote this, we had basically that text input was wrapped
inside of an observable and we were using regex to check the input. It was a very similar kind of pattern except
we weren’t using switchMap because you want to keep all the characters. But with the just Hooks version, it works
really nicely and it’s just Hooks, there’s nothing else. So you’re using the handlers to set state
when all those conditions are met and the one part I found really tricky was to get
the submit button to work properly, because if you kind of like backed out and went forward
and backward a little bit on the password, the submit button would sometimes get stuck,
so that was kind of a fun learning. So here are my tests and there’s just really
simple regexes, and these are my handlers, setting state and this is the gotcha. Is that I was trying to do this with set state
and it turned out that I needed the use effect Hook. Because use effect will kind of kick off a
new render every time something changes, so that was kind of cool. So my last example, are you guys all still
reading? So this is another kind of like classic use
case for RxJS, especially when I first started learning about t because you basically, you
know, we talked about streams and how streams are kind of — a stream of anything could
be a stream of mouse locations. So here you’re capturing those mouse locations,
you’re observing those mouse events, like drag, mouse drag, mouse drop, all of those
things that happen when somebody is dragging and dropping and you’re animating those user
movements. So this is my — I just always wanted to do
this. And I finally had a reason. So — yeah, it was really annoying to — when
the dragon kept flying, so I decided to make it only fly part of the time. So anyway. This is — let’s see, yeah, very simple version,
oh, yeah, that was the right slight. Sorry about that I’m bad at this clicking
thing, apparently. So I actually was kind of setting out to do
this with RxJS and then I found out that there’s this HTML drag and drop API and that makes
it super-simple, and then just some Hooks to implement the handlers, and so I’m not
saying that you shouldn’t, like, use RxJS for this, but I found out that you didn’t
actually need to. So I just feel like there’s a lot of different
ways to kind of like drop your dragons. [laughter]
So this is — this really minimal, like, demo only version was less than 40 lines of code,
which I think is kind of amazing and that’s all thanks to the HTML drag and drop API. So in conclusion: Today we learned about observables
and streams. We learned about a few different ways to use
these patterns, and we looked at some different implementations, including our surprise guest. And so that’s it for me, I’d like to send
out some things, especially my team at work, Josh Mortensen is a God. He makes my terrible slides and make them
look beautiful. Even though I’m an artist, I’m bad at this
kind of art. So thanks for that.>>I’d like to thank React Rally for having
me back again. This is just a very magical experience being
here at the risk of sounding like super hippie-dippy, I love this place. I also would like to thank my partner for
putting up with all the stress of the past few months and all the goats. [cheers and applause]