Transcript from the "Observables Introduction" Lesson
>> Jafar Husain: Why are observables important? Why are they powerful? And you should learn them. Well it's quite simple. Almost every UI, when you do some interaction with it, you see the same progression. You listen for an event, the user does something, then you might make an asynchronous request right to the server and then maybe follow up with an animation.
[00:00:23] Observable is capable of modeling all three of these things. So if you model all three of these actions as an Observable in your user interface, you can then use the functions that I'm gonna be teaching you guys about today to compose them together seamlessly. There with very, very little code.
[00:00:39] And so that's why observable is powerful and important. It's capable of modeling all of the three most common actions that you see, asynchronous actions, you see in user interfaces. So in order to get the observable type today, I'll be using the reactive extensions library. it's a library that you can grab out there.
[00:00:54] It's an Open Source Apache2 library, and what it is, is it introduces observable type but then it also defines all of the array methods I'm gonna be teaching today and many many more over the observable types. So you can use those methods to compose together observables instead of arrays.
>> Jafar Husain: So this is a site where you can go to grab it but it will be included in the exercise you do later see don't need to worry about too much. Now, the problem is we have all these old async APIs, these weird shaped async APIs out there.
[00:01:24] The DOM API is one of them and our goal, the first thing we need to do is we need to be able to take all of these weird async APIs and adapt them into observables. And the observable library comes with some helpful functions to help you do that.
[00:01:37] So for example, the fromEvent function, will take a DOM event and the name, excuse me will take a DOM object and the name of the DOM event and adapt it into an observable. And so then now you can forEach over that observable, which is exactly the same as doing it add event lesser, move event lesser.
[00:01:53] So let's take a living example. So we want to take all of these different APIs and adapt them into one common interface capable of modeling all of them. So here is how you subscribe to an event, hopefully most of us are familiar with this process, right? We take an event handler and we add it to some DOM node, in this case that I'm using the document but it could be a button, it could be a link tag.
[00:02:17] And so we give it the name of, I think I made a typo there, it should be mousemove not mousemoves, but we give it the name of an event and then we associate with it a call back. And then every single time a mouse move or in this case happens that callback gets invoked and that event object describing information about the mousemove is pushed at us, right, by our callback.
[00:02:38] Now here's how you would do the exact same thing with an observable. So, you can take any observable, that observable that we adopted from a DOM event for example. And you can just forEach over it and accomplish exactly the same thing. We're passing in a function, which gets invoked for every item in the observable.
[00:02:57] And what comes out though is this subscription object, this is where the observables forEach method differs from an arrays forEach method. Remember that in arrays forEach method, when you do forEach over an array it's gonna complete synchronously, immediately, right? forEach is gonna run through all the items in the array and finish.
[00:03:13] Not so with an observable, because remember an observable is a collection that arrives over time and so when you forEach over an observable, it's not like when you just block and wait for all the data to arrive and then just block the system. We don't wanna block in fact.
[00:03:27] So what a forEach does it actually it doesn't block it completes immediately but then as the observable items in the observable arrive over time, that function gets invoked. So it's just like a DOM event where you hook up a handler, and then immediately you're not blocking, and then if those mouse moves arrive, it gets pushed to your handler.
[00:03:43] Now if your forEach over data, right, because this goes on for a very, very long time, you might decide that you don't care about that data anymore. You might decide just like you stop listening for mouse moves for example, you might decide you don't care about the data coming out of observable and so we need some way to unsubscribe from an observable.
[00:03:59] And that's why the forEach method on an observable, not an array, returns this subscription object. So if you decide you don't want to receive messages anymore, that's one thing I forgot to call out earlier which is with an observable, the consumer should be able to say look, I don't care about those messages.
[00:04:14] That's different than the producer saying done. There's no more stream. There's no more data coming. The consumer can say, you know I don't care if there's more data. I just don't listen anymore, right? That's the equivalent calling remove that listener or here calling the dispose method on the subscription.
[00:04:28] So the the previous slide and this slide were really doing exactly the same thing, observable hasn't added any value. It's doing the same thing that you would do with a DOM event. It's this next slide where we're gonna demonstrate the value that observable adds over and above as a DOM API event listener interface.
>> Speaker 2: Question, is there any plans to add observable in ES7, or any of the ES.next?
[00:05:06] It's just in the early processes, so no guarantees, but regardless of whether it makes in the language or not, there's nothing stopping you from using a library.
>> Speaker 3: Just the water bottle making a lot of noise.
>> Jafar Husain: Absolutely.
>> Speaker 3: Sorry about that
>> Jafar Husain: Yes, and so the answer is yes.
[00:05:54] So, the first event handler here is for receiving data, right? That's just like the adamant listener, callback that you hand to the DOM event. But these next two callbacks are optional. This callback receives an arrow, remember arrow means function guys. I know a little bit tough to remember the new syntax but all of this is just a function which accepts an heir and then does something, in this case we just put it out to the console.
[00:06:14] And then beneath that, there's a function with, this is the syntax for a function that accepts no arguments. So this is a function that accepts no arguments. This whole function just gets invoked as a way for the producer to tell the consumer, no more data. That's why it accepts no arguments.
[00:06:28] We just call that function to tell the consumer no more data is arriving. Does that make sense? So here are the two missing semantics that are there with aerator right? When you call next and it says done true or when you call next it throws that we've now added to push streams by this observable interface.
[00:06:45] So here's how you can get pushed the information that an error happen or get pushed the information that well there's no more data in the stream, that make sense, yeah question? Is this forEach?
>> Speaker 2: Could you have added any number of functions there or is this really specific forEach that excepts up to three?
>> Jafar Husain: Specific forEach that except up to three cuz we're trying to create the same semantics for push streams while you're receiving information pushed back to you that we have for iterators, where you're pulling information out, and so when you're pulling information out of an array, you can either get a value.
[00:07:15] You can attempt to pull information out by calling next, and it can throw, so you can get an error, or you can pull a value out and that done can be true, telling you that there's no more data. Here, we're trying to create the same semantics the other way around.
[00:07:28] So if I'm pushing you information, I should be able to also tell you that an error happened, or tell you that there's no more data coming, and that's what those last two functions do. So you provide, it's like, so think of an observable provisionally while you're trying to get your head around the concept.
[00:07:41] Think of observable as like a DOM event, where you can pass three handlers instead of one. And those last two handlers tell you whether an error occurred, or whether there's just no more data coming along, is that makes sense? So observable right now, the mental model I want to use is all is the observable is like a little like an event that's a first class object that you can give three event handlers to, instead of one.
[00:08:03] So technically if we, this is, it is also just shorthand for this. You actually give it an object. This is what we call an observer object. So those three callbacks are actually just shorthand for providing an object with three callbacks, on next, on air, and on completed, right?
[00:08:17] And then the observable accepts an observer and invokes onNext, onNext, onNext, onNext until it invokes either onError or onCompleted, is that make sense? It doesn't call on air and then all uncompleted, right? It will either just tell you an error occurred and that means that the stream has ended.
[00:08:36] No more data's coming because an error occurred. Just like when you throw in a function. That function's not going to suddenly return a value, right? When you throw inside the function, it's done. So that's how the observable works. You've got an observable. You, if you wanna consume the data inside of an observable, create this little object with three handlers, you hand the observer object to an observable.
[00:08:54] The observable pushes data into the observer object and by extension your callbacks. And it'll call onnext, 0 to n number of times followed by either an on air, or an uncompleted. It might actually never call onError onCompleted because some stream is gone forever. MouseMoves, you would never get on error or on completed call, if your observable was just wrapping a mouseMove event, right?
[00:09:16] Because that's a stream that just goes on forever. It's perfectly okay to have an observable that goes on forever. Question?
>> Speaker 2: Just question about, can you still align it declares mouseMoves? Is that a new observable?
>> Jafar Husain: It's right back here. So we actually created it by using a function provided with the Rx library, to help you adapt an event into an observable.
[00:09:38] I wanna see this the actual definition of this function in just a moment. This fromEvent function which can take any DOM event and event name and combine them and create an observable type. Is that makes sense? So it's just the same, and we're just adapting the interface. So when you call forEach on mouse moves, under the hood, it's adding in the event listener to the mouse move event on the DOM object.
[00:09:57] So we're gonna see how this works in just a moment. Yep, do you have a question? Sorry.
>> Speaker 2: No nothing came up online or anything. Do those events or the function have to be in that order next onError, onCompleted?
>> Jafar Husain: Not here, so in this particular overload when you're passing in, it allows you to pass in either a collection of like not a collection, but it allows you passing either arguments that are functions or you can pass in this object, right?
[00:10:24] So if you wanna be able to specify them in any order, you can pass on the object because that's just name value pairs there, so you can rearrange that however you want. But today for most of our exercises, we'll just be using this form where we just passed functions.
[00:10:35] And in this case, yes it is order because it's based on argument order. So you get on the next function, first the air function second and the completion function last. Does that make sense?