Transcript from the "Questions: Observable vs Promise, etc" Lesson
>> Audience 1: So, why do you prefer using observables to promise?
>> Lukas Ruebbelke: So, the question is, why do I prefer observables to promise? The main reason being that a promise can only ever return a single value. An observable can return many values over time. So, are we hanging out tomorrow?
[00:00:30] Are you coming to the workshop? Just when I'm getting to the good part. I mean, we had some bread. Maybe some, I don't know blooming onion or something. We finally had our dinner salad and tomorrow we're gonna sit down and have steak and really get into it. But I think you can stream and if you can, they I talk a lot about this but the idea is that with an observable, so I almost have to, I'm like do I jump in.
[00:01:06] Do I [SOUND]. Let me show you actually one image real quick.
>> Lukas Ruebbelke: All right, I can't help myself. You guys gotta hear me talk about observables for at least five minutes. I'll talk about this tomorrow, but,
>> Lukas Ruebbelke: I believe there's two really main problems, or rather kind of two and a half problems when it comes to an application or maintaining an application.
[00:01:41] So, you've heard me talk about complexity as it involved state, control flow and code volume. So, this is actually a quote that comes from a paper called Out of the Tar Pit. And I believe it by by Ben Moseley and Peter Marks if I'm not mistaken, so this is something that Victor Savkin shared with me.
[00:02:01] It's about a 65-page, I think it's like a dissertation or it's some kind of very high level PhD style white paper. But, I recommend everybody read it. I read it like three or four times just to wrap my mind around. The main this is probably the first 20 pages is really where you're gonna get the most value.
[00:02:25] Cuz then, it kinda veers off into kind of academia, etcetera. But he makes this, they make this really good quote at the beginning. In that the biggest problem with applications is complexity. Complexity is the result of state, and as a result of state management, we have control flow issues, and code volume, that comes from that.
[00:02:49] So now, with that as the context I believe the two biggest problems that we have especially in an angular app in this context is one. How do we manage state and how do we communicate that? So when something changes, how do we tell the rest of our application that hey, this thing happened?
[00:03:10] And so, we've actually had two very classy design patterns to address this. So for state or managing state, we have the iterator pattern. And so, what this does is it allows us to take a collection and incrementally pull values off of it, so we're gonna say next, next, next, next until it's done.
[00:03:34] At the same time, we have a pattern that's very well suited for communication. That's the observer pattern. So, any time some indeterminate event happens, that we can communicate that to our consumers. That, hey, this thing happens. So, by combining these two patterns together, we have an observable. Which allows us to communicate state over time.
>> Lukas Ruebbelke: And so this is what an observable stream looks like.
>> Lukas Ruebbelke: We have time and as things happen along this timeline. We can perform calculations and either drive new state, receive new state, or transform state as we move along. So along our timeline, we have events and then with each event, we have the opportunity to do something.
[00:04:39] So which http, I think people kind of have a superficial understanding of observables, because they've done .subscribe and that's as far as it goes. Because an http call is really just a single value, you call a server, you get something back and then set a rather a restful call.
[00:05:03] But for instance in the case of like, let's say fire base or a real-time web socket, that streaming data overtime. Well, this is something that is actually you're getting additional values as they come in. This is where you would want to, or this is where a promise would just not be appropriate at all, because a promise can only ever return a single value and that's it.
[00:05:30] But, what happens if there is another value, or another value, or another value? And so, this is where observables come in. So, observables are very well suited to handle a single value, just like a promise. But, they're also suited to not only handle one value but multiple values.
[00:05:51] So, that is essentially kind of the deal. If you can think of, a promise is I think of it as a courier in a sense of like, there's a letter. I'm going to deliver it and I'm done. Mission accomplished. Whereas, an observable is more like a telephone connection like you're actually on the phone until you're ready to hang up.
[00:06:15] So, you can continue to communicate these events. now where this gets, to me I think the best application to learn wrap your mind around this observable stream is from UI events., Because whether you we notice it or not, we are always admitting and streaming dom events as we interact with our application So for instance, if we are dragging our mouse across the screen, we are emitting.
[00:06:46] They're happening whether we're capturing them or not. And so now, using observable, we can actually capture those things and Do something with them. And so, not only do we have the ability to consume multiple values, but those values are completely encapsulated within the observable stream. And because the observable operators are pure in nature, meaning no side effects, that you can then stack them on top of each other.
[00:07:19] And essentially, perform as many transformations as you want, until you get to the end of the road, your subscribe block. So, subscribe, dot subscribe is kind of the equivalent of really just invoking the observable streams. So, think of it like this, I'm actually calling this and I wanted to now, essentially, flip the switch, and it's on is that once your data gets to your subscribe block.
[00:07:45] It should be in it's final form and Ready to dump, or rather, ready to consume and put right into your application. So, when I started with observables, kind of the very first naive attempts Is I would say okay, give me this data from this server, and then within my subscribe block is I would start fiddling with it.
[00:08:10] And okay, now, I need to loop over, and I need to do this, and I need to do this, and I need to do this. And then I realize, I can actually do like .map, like an additional map, like .filter. You know da, da, da. And by the time it gets to my subscribe block it should be exactly in the shape that I need.
[00:08:25] And so being able to actually stack these operators on top of each other. And so this is for, especially doing like data dashboard stuff. Or like payroll or you know, whatever, any kind of data transformation. Here's this raw collection, and at the bottom of the stream, because we've stacked these essentially peer functions on top of each other is really just totally functional.
[00:08:50] Peer, no side effects. It just kind of flows through this funnel and when it gets to the bottom it's now in the shape that you want. And so we're kind of familiar with this, if you use for instance like low dash, you can actually chain kind of these higher order functions together.
[00:09:05] I want a filter, I want a pick, I want a map, I want to do these things. And at the end of it I wanna get that value. So this is a similar experience with observables, so that we can now like stack these things on top of each other.
[00:09:21] Does that make sense?
>> Audience 1: Yes.
>> Lukas Ruebbelke: I think it will make more sense if you can actually stream tomorrow, it's my most hopeful desire that you can, but that is kind of the five minute elevator pitch.
>> Lukas Ruebbelke: When I think of observable, it's just a single event. I think of promises as a single event.
[00:09:40] I think observables as really an entire, almost a warship if you will. That it does tons of stuff. And It's almost like an event state platform unto itself.
>> Lukas Ruebbelke: Next question. Shall we talk about love, life, heartbreak?
>> Lukas Ruebbelke: Bro you're not sneaking out, I can totally see you, you're right on the front row.
[00:10:13] This, you're busted. Yes.
>> Audience 2: Sorry to keep you on observables here, but-
>> Lukas Ruebbelke: Love to talk about them.
>> Audience 2: In your example with the API you called the get widget. You're only going to call that once from your app, how is that different from a promise? You're going to get your response, what's the difference?
>> Lukas Ruebbelke: So in this case for consuming the value it's exactly the same.
>> Audience 2: Okay.
>> Lukas Ruebbelke: We see-
>> Audience 2: I get what you said when you say we're observing events that are coming from our template.
>> Lukas Ruebbelke: Let me see if I can show you a better example. So skipping through all these slides, don't peek.
>> Lukas Ruebbelke: So here's an example. So I think really UI events, when you start to actually think of it from the interface first, then I think stream start to make a lot more sense. Now, what if you actually wanted to capture like an event click, and resolve for do something in resolved that is a promise.
[00:11:08] Like, once you do it once that's it, you can only resolve a promise one time but with an observable stream.
>> Lukas Ruebbelke: That you can capture clicks over and over and over and over. And so that's where every time I click I want to reevaluate or recalculate some value.
[00:11:33] And so clicks, mouse events, mouse moves, anything where something can continue to emit events, that's where observables. So I think maybe a better way of thinking it of it is that well like promises and observables like. In the term of an ACP call, like they're exactly the same.
[00:11:52] Well, in most cases, yes. But, pound for pound, there's nothing a promise can do, that a observable can't do better. So, that alone is, like, I'm just going to use observable. And even then, as I thinks it's, one, as it returns an observable, to actually get it back to a promise you actually have to do that extra step.
[00:12:13] But you have essentially resolving a single value from an async call, that's boring. But where it's really cool is for things that continue to emit values.
>> Audience 2: Sure.
>> Lukas Ruebbelke: And when we actually talk about redux in an application store, that as you change things in application store, it continues to actually emit those values.
[00:12:38] So I think the idea is making an async call, they're kind of pound for pound. It's like yeah, in this isolated example, but what about the other 10,000 things that you can use observable string for. Yes.
>> Audience 3: Chris had a question several minutes ago now.
>> Lukas Ruebbelke: Sorry Chris.
>> Audience 3: No, that's my fault. I don't want to display a part of my page until I get my data from the service, and I don't wanna use resolve. Currently, just using an is-loaded Boolean, and set it to True once I get my data, and wrap my def in an NGF is-loaded, is there a better approach to this?
>> Lukas Ruebbelke: So, you can leave it essentially undefined.
>> Lukas Ruebbelke: Initially, and then just check to see is this, does this have a value? So let's actually try that out. Let's see what happens. I hope I don't get embarrassed. Oops. There we go. Tweet deck. I'm getting embarrassed. All right.
[00:13:44] So, let's go to our widget's component. And so, you can see here, initially, widget does not exist. Or rather, it's undefined. Like, it's defined. But there's certainly no value. So it's there, but it's of value undefined. I think that's correct. So if we go here.
>> Lukas Ruebbelke: ngIF.
>> Lukas Ruebbelke: This may or may not work.
[00:14:41] I don't know if I've tried this.
>> Lukas Ruebbelke: ngIF widgets, widgets, widgets, [INAUDIBLE]. Did I break this?
>> Lukas Ruebbelke: Can't have multiple template bindings with All right. Don't be mad.
>> Lukas Ruebbelke: Yeah, all right let's refresh this. it's already there let me just clear my cache maybe. There's probably a way in chrome to actually slow this down.
>> Audience 4: You can put a pause in your service call before it returns it's values.
>> Lukas Ruebbelke: A pause.
>> Audience 4: Like in your mapping or something.
>> Lukas Ruebbelke: I could.
>> Audience 3: [INAUDIBLE]
>> Lukas Ruebbelke: I could do a time out. [SOUND] Let's do it here. So timeout. No, I just wanna use the native timeout.
>> Audience 2: Ooh, setTimeout.
>> Lukas Ruebbelke: Is it setTimeout?
>> Audience 2: Yep.
>> Lukas Ruebbelke: Yeah, okay. So is it function then interval?
>> Audience 2: Yes.
>> Audience 3: Yes.
>> Lukas Ruebbelke: Okay, yes, that was so forceful.
>> Lukas Ruebbelke: So, is it okay? All right, let's see, I don't know, Yolo One, two, three, boom. All right, so all I've simply done, in this case, is ngf will evaluate to false if something is undefined.
[00:17:27] And so here, I'm just saying if it exists, show it. And if not show not here, I think there is a throttle in Chrome dev tools
>> Audience 4: Yeah Chris that I mentioned that
>> Lukas Ruebbelke: So that's another way to do that. Yes, next question
>> Audience 4: Dale is asking you subscribe to an observable, that implies an unsubscribe Are there garbage collection leakage issues associated with cleaning up observables?
>> Lukas Ruebbelke: So I don't wanna answer that question, cuz I think it's stupid. But what question do you have?
>> Multiple: [LAUGH]
>> Audience 3: I have a different question.
>> Lukas Ruebbelke: No, what?
>> Audience 3: No, back to the-
>> Lukas Ruebbelke: Is that a different Dale?
>> Audience 3: No back to this other question, of showing something else, you said you could put it inside the directive
>> Lukas Ruebbelke: Okay just to clarify that was a different Dale, I thought that was you
>> Audience 3: It was [LAUGH]
>> Lukas Ruebbelke: Okay that was definitely stupid
>> Audience 3: Okay thank you, inside the template when you have a new component you could put the value in there and it would get replaced.
[00:18:25] Wouldn't that be a place to put your wait for it
>> Lukas Ruebbelke: I'm sorry one more time?
>> Audience 3: Well when we do a selector.
>> Lukas Ruebbelke: Mm-hm?
>> Audience 3: And we could put a loading inside of that, wouldn't that be a way to address-
>> Audience 5: Just like
>> Lukas Ruebbelke: Right, so it only, actually, interesting question.
[00:18:49] I've only ever tried to do this on the main component. Well, okay. Yes so if we do that.
>> Lukas Ruebbelke: Let's see.
>> Lukas Ruebbelke: So, no. That actually, that one worked, because the widget's list component will load immediately, and then the actual data for the list will actually happen. Like so asynchronous point.
[00:19:30] So the problem is that your component will render and then as things come in it will attempt to render those as well.
>> Audience 3: So it really only works at the app level while you're bootstrapping.
>> Lukas Ruebbelke: Yeah, because there's no angle to actually do anything. So it actually does truly have to bootstrap.
>> Audience 5: Okay, is that along the lines of ngCloak?
>> Lukas Ruebbelke: Yes, but that kind of solves that problem. The fact that-
>> Audience 5: Sometimes-
>> Lukas Ruebbelke: Nothing renders until it's there.
>> Lukas Ruebbelke: Also, because any type of DOM manipulation is wrapped in the template tag. And so that is the browser wanna ask you render a template tag until it's been initialized or until there's actually content inside of it.
[00:20:16] Or they're some event in which template tag will be. I didn't even know it's a real tag until actually I was reading the doc some template. What is this? It actually has to do with the web component spec. And it doesn't, there's a certain point at which it will not actually render until other things are in place.
[00:20:34] So that solves that kind of flash of unstyled data sorts. Okay, I feel like there was another question about unsubscribe. Dale, would you like to ask that now?
>> Multiple: [LAUGH]
>> Audience 3: Well if is was just a question of you subscribe to things like a lot of times in Java if you subscribe as a listener to things, then you can end up leaking things because somebody holds a reference, does crap with a weak reference.
[00:21:05] So I'm wondering if you start subscribing to a lot of things, if you pin things in memory?
>> Lukas Ruebbelke: You can, so this is what onDestroy is for. That when you call that subscribe, that actually returns essentially an unsubscribe method. If you actually look at the source code in the constructor, that's what it actually returns is a method to basically kill itself.
[00:21:36] And that's where you would use onDestroy. Essentially unsubscribe from anything including observables.
>> Audience 3: So if I do a service call, subscribe to it, then I should do the onDestroy thing and unsubscribe.
>> Lukas Ruebbelke: That would be a very boy scout thing to do.
>> Audience 3: So it's not necessary?
>> Lukas Ruebbelke: So browsers in Angular 2 is very, very performant and it's very good about cleaning that up.
>> Audience 3: Okay.
>> Lukas Ruebbelke: So you're probably going to be okay. But at the same time you're not going to offend anybody by being a good neighbor.
>> Lukas Ruebbelke: Next, if there are no more questions in the next three seconds, I'm kicking everybody out. Yes?
>> Audience 1: How is the API set up on the local What 3000 or whatever it is.
>> Lukas Ruebbelke: Uh-huh.
>> Audience 1: How is that set up cuz our site is running on 2200.
>> Lukas Ruebbelke: Uh-huh.
>> Audience 1: So somehow we can get to the json through.
>> Lukas Ruebbelke: So that's actually json server which is just another mpm module.
>> Audience 1: And somehow [INAUDIBLE]
>> Audience 4: If you look in the kit, there's a server directory at the same level source.
>> Audience 1: Yeah I see it.
>> Audience 4: Okay.
>> Audience 1: But how does-
>> Audience 4: So-
>> Audience 1: It know to open up that port.
>> Audience 4: If you look in the MPM start stuff you'll see the JSON server.
>> Lukas Ruebbelke: And so if we go to package.json or packages.json. On line seven, I'm basically saying, concurrently, I want to run server.
[00:23:29] Which is essentially the line eight, which we're calling spin up JSON server. And watch this db.json file.
>> Audience 1: Okay.
>> Audience 1: Thank you.
>> Lukas Ruebbelke: And so completely unrelated to Angular2, this is a great way to spin up a rest API really quickly. Now I've actually done projects where we're full steam head on the UI.
[00:24:04] And services are handled by another team, and actually in one case, another company. And who knows when they'll be done? But because we can agree on really the interface of this is what we're going to get at some point. We just basically mocked out a bunch of data.
[00:24:21] Served it up using JSON Server. Built everything. And then when it was ready, we just dropped it in and it was good to go.