Check out a free preview of the full Asynchronous Programming in JavaScript (with Rx.js Observables) course:
The "distinctUntilChanged()" Lesson is part of the full, Asynchronous Programming in JavaScript (with Rx.js Observables) course featured in this preview video. Here's what you'd learn in this lesson:

To further optimize the search suggestions, Jafar what only changed values to be sent to the server. While there are a number of ways to implement this, he chooses to introduce the RX.distinctUntilChanged function which will only update the stream when a change has occurred.

Get Unlimited Access Now

Transcript from the "distinctUntilChanged()" Lesson

>> [MUSIC]

>> Jafar Husain: Now the autocomplete box could probably be a little bit better. It's probably not ready to ship just yet. I'm probably gonna turn around throw this in production. How can I make this better, this auto-complete box?
>> Speaker 2: You can make the result matter if your in JSON.
>> Jafar Husain: [LAUGH] That's true.

[00:00:19] I like that one but this course isn't about HTML formatting so why don't we come back to that. That's a totally fair request but I don't want to spend a lot of time with CSS, you can learn that in another class. I'm sure Front End Master's got some great classes for it.

>> Speaker 3: People don't often type things in correctly the first time they backspace then they go forward and back.
>> Jafar Husain: Yeah, yeah, that's interesting, they backspace. What's going to happen if somebody backspaces?
>> Speaker 2: I think it's gonna work.
>> Jafar Husain: It will probably work, but will it be optimal. If I literally hit the backspace key, what will happen?

>> Speaker 2: It's a key press.
>> Jafar Husain: It's a key press. So it'll trigger another request. Maybe that's what we want because if we went from ab to a we should trigger a request for it. But what happens if I go left to right? It'll work kind of. It'll also hit my server for a network request for the identical text because key presses are key presses.

[00:01:17] How can we make this better?
>> Speaker 4: Caching?
>> Jafar Husain: Caching is absolutely true, right. But the question is, cache where? Right, you could cache at the http layer, you could cache in memory, right. Presumably if the server is caching its search results at the http layer, caching might not be as important.

[00:01:34] You could probably do a little bit better by caching it in memory but that's not what I'm after. I'm after just making sure we don't issue that request at all. Cuz I don't know if under the hood it's cached.
>> Speaker 3: Limiting it to alpha numeric characters?
>> Jafar Husain: Yep or we can filter for the key code.

[00:01:49] We can absolutely filter it for the key code. The fact is that there's a lot of those key codes and I mean that's a totally reasonable approach. There's actually a really helpful RX operator I want to take this opportunity to teach you right now. And the way it works is if you think about it.

[00:02:02] What we're really doing is when we take keypresses, I actually want to break this up a little bit. I wanna show you guys that maybe this warrant's breaking up. This is as nice and short as this query is, why don't we instead of going directly from the key, directly to the search results.

[00:02:19] Why don't we just break it into a couple steps and the reason for that, you'll see in a moment. So I'm gonna go from the key to the search. So now, instead of ab, we have,
>> Speaker 5: Now you have a stream of input values that you can do to the collapsey thing to compare the values to see if they changed.

>> Jafar Husain: You're right. Now, we've turned it from key presses, into searches. And now with searches, we should be able to do some sort of thing to make sure that we don't get two searches in the same stream. And it turns out there's a helpful operator, called Distinct Until Changed, that will compare successive values in a stream and will be dedupe them for us.

[00:03:02] Okay, so let's try that out. So now that we've got searches, I'm gonna make this code work again cuz now we need to map search into this, and so instead of returning input.value. I'm gonna return or, text box.value, I mean, I'll just return search so you notice how that went from key presses to searches?

[00:03:25] And then we map from searches into searchResultSets and then we flattened and we're good.
>> Jafar Husain: Okay, so now that I've got this stream of searches, I am going to run distinctUntilChanged.
>> Jafar Husain: And that turns something like this
>> Jafar Husain: Right, if we hit the left arrow we'd end up with a stream like this right because it's still the same searche, it's ab and then av right.

>> Speaker 3: And then you have to hit the right arrow.
>> Jafar Husain: Yes and you'd hit the right arrow exactly into.
>> Jafar Husain: If ever you are in doubt of what your stream looks like try and write it out. Try and write out and visualize each step. It's really important cause let's face it it's hard to picture all the stuff in your head and console logging it works great for arrays.

[00:04:24] But you can't console log an observable data structure, right? If you have an array in memory. You can console log it and you can see it all in JSON. But you can't console log an observable. You can put breakpoints in your handlers, right? But this is where you're going to have to actually sort of live in your head a little bit.

[00:04:40] And it helps to get that stuff out on the page and sort of see what it looks like. So that, is going to take this stream and turn it into this stream. Right because we got two abs in a row in the stream and we de-duped them to just ab.

[00:04:52] Does that make sense? So now let's try and I don't think we'll see a result but we'll know we'll know that it's worked. We'll see less network requests. We could probably see that if we went down the chrome. Uh-oh
>> Speaker 3: Did you save?
>> Jafar Husain: No, I'm not saved.

[00:05:11] But I don't expect that I need to save that action.
>> Speaker 3: Usually it says like locked or something when you click save.
>> Jafar Husain: Okay.
>> Speaker 3: Or freeze. It turns to freeze.
>> Jafar Husain: Well, run would presumably work.
>> Jafar Husain: I might have a typo or something.
>> Jafar Husain: Let's comment out distinctUntilChanged and see if that's the problem.

[00:05:35] Input.value. It's textbox.value. I'll save and run, and now we have our auto complete hopefully
>> Jafar Husain: Has somebody actually been changing the text box? I think somebody changing it out from under me because before that text box appeared to the right maybe not maybe I just made that window smaller.

>> Speaker 5: I think it's smaller.
>> Jafar Husain: Yeah that's what it is I'll leave it like that, it looks better. Textbox.values not working. Let's just make sure I don't have a I'm seeing a little air here. Is Plunker helping me out?
>> Speaker 6: Map search should be map function search.
>> Jafar Husain: Thank you very much.

[00:06:20] This is why I love the arrow function. I never make that mistake with arrow functions. Thank you, Plunker. It's actually turning out to be a pretty nice tool.
>> Speaker 7: Yeah, yeah, it's working, especially with the streaming. Hopefully worth the wait.
>> Jafar Husain: There we go. And if I make a left here, now, how can I prove that I'm not making any outgoing network requests?

[00:06:41] Let's just keep me honest here. Always good to keep me honest.
>> Jafar Husain: And bring up the Network tab Plunker might just make an arbitrary network request I'm not sure, but we hit-
>> Speaker 7: You can shrink the size of just that debug tool without you know like click over here focus on the debug thing and then I think somewhere down-

>> Jafar Husain: We just want to make sure it's readable for the folks at home.
>> Speaker 7: Yeah that, that.
>> Jafar Husain: So I am going to clear out the network requests and we're gonna hit b. We should see a network request bam. But now if I go left a no network requests right?

[00:07:18] Cool.