Async Pipe
Get the project source code below, and follow along with the lesson material.
Download Project Source CodeTo set up the project on your local machine, please follow the directions provided in the README.md
file. If you run into any issues with running the project source code, then feel free to reach out to the author in the course's Discord channel.
Lesson Transcript
[00:00 - 00:05] Welcome back. In the previous lesson, I emphasized the importance of always unsubscribing from a subscription.
[00:06 - 00:08] Well, about that. I have to confess, I lied.
[00:09 - 00:20] There are some use cases when you don't have to unsubscribe from a subscription You will also hear from other people that you don't have to unsubscribe from HTTP calls. Let me explain.
[00:21 - 00:27] I will draw two data streams in here. The first one is a finite stream and the second one is an infinite stream.
[00:28 - 00:40] A finite stream of data is a conceptualization of an observable that emits only zero or one value. So when we subscribe to our observable, we expect either to get nothing or only one value.
[00:41 - 00:51] After we get nothing or one value, the observable will complete. And what happens after an observable completes, it will automatically unsubscribe from all its observers.
[00:52 - 01:06] This is why people say that you don't have to unsubscribe from the HTTP client because it is a finite observable. Now, an infinite observable does the same thing with the exception that it will emit an infinite amount of times.
[01:07 - 01:22] The only way for it to complete is if we manually unsubscribe from it. Infinite observables are usually events such as a mouse click or whenever we type into an input field in a form, we get new events emitted.
[01:23 - 01:30] Now, the HTTP client will clean itself up. So we don't have to worry about unsubscribing, until we do have to worry about unsubscribing.
[01:31 - 01:36] And this is the case when we have side effects. For example, let's say we have a user form in here.
[01:37 - 01:51] What this form does it will ask the user is logging credentials and after filling those in, the user will click on login, request will be sent to the server. And let's say we have a really, really slow server.
[01:52 - 01:57] The user gets bored and he decides to navigate away from the login form. That's fine.
[01:58 - 02:13] And the user is expecting that he didn't log in. Now, because we subscribed inside this form, the subscribe handler will run eventually, even though the user navigated away from it, because our observable will eventually complete.
[02:14 - 02:20] As you remember, it's a finite observable. So it can either have zero results or one.
[02:21 - 02:30] So in case of zero results, it means it will error. And let's assume we have an error handler and we want to display a notification to the user.
[02:31 - 02:39] Our user is already on another page and he assumes that he is not logged in. And suddenly he gets a notification.
[02:40 - 02:47] This will raise some eyebrows and the user will not know what actually happened in there. It will be at least confusing for the user.
[02:48 - 03:02] This is not too bad. It's only bad user experience, but in reality, nothing bad actually happened. Now let's assume we eventually get a response from the server and the server be like, hey, I finally processed your request.
[03:03 - 03:08] Here is a token. And in the subscriber handler, the token will be set in the browser.
[03:09 - 03:19] Now we have a token, even though the user is assuming he didn't log in, but we have set the token for the user in his browser. So there might be some side effects in there.
[03:20 - 03:29] Another use case is let's say, let's go back to our error scenario. Let's say we get an error message in there or a handler is handling this error.
[03:30 - 03:37] And then there is redirecting there. The user is already browsing another page is interested in something else.
[03:38 - 03:48] And suddenly he gets randomly redirected to a new page. Now, okay, this will be very confusing for the user because he definitely did not expect this to happen.
[03:49 - 04:05] As you can see, we need to be mindful and careful about it. But I think personally, it's always a good idea to unsubscribe from your observable because this way, even though you only have an HTTP call, always assume that the observable is infinite.
[04:06 - 04:16] This way you don't have to worry about unsubscribing from an observable. Now that you've seen why it's always a good idea to unsubscribe, even though some people might say otherwise, let me tell you the good news.
[04:17 - 04:25] And the good news is that there is a simpler way to handle all this boilerplate from subscribing, unsubscribing. And it's called async pipe.
[04:26 - 04:39] For those of you who do not know what a pipe is, it's basically when we have a function, the output from the left side will get passed to the output to the right side. We can do this as many times as we like it.
[04:40 - 04:54] So the output from here will go into here, then we execute this function, the output will go in here, and so forth and so forth. If you've worked with Linux or PowerShell, this is something very familiar.
[04:55 - 05:02] So let me demonstrate to you how this works in practice. The async pipe will do the subscription and unsubscription for us under the hood.
[05:03 - 05:06] So, let's remove that in here. We don't need it anymore.
[05:07 - 05:11] Let's remove the subscription as well. Let me remove that.
[05:12 - 05:22] As I promised, we don't need to subscribe anymore. The code looks much simpler, but how do we get this data from our fetch products into our product list?
[05:23 - 05:29] In here, we need to pass the observable itself to our product list in here. Let me create an observable.
[05:30 - 05:33] I'll use the same type. Now I have created this observable.
[05:34 - 05:46] By the way, when working with observables, there is a convention to annotate observables with a dollar sign. And now that I have my observable, let me assign it and let me add an exclamation mark in here.
[05:47 - 05:52] We are set up. Let me remove those unused imports.
[05:53 - 06:03] Alright, and the last thing is, let's pass our observable. Let's add the async pipe. And it's complaining because we haven't added our async pipe to the imports.
[06:04 - 06:06] We have added it. Let's save.
[06:07 - 06:19] Now it is complaining because in here for the first time, our observable is NULL. And then during ngOnInit, it gets an observable assigned to it.
[06:20 - 06:28] That's why we see it in here that the type is product list or NULL. We can fix this in different ways.
[06:29 - 06:36] The first one is to wrap it in parenthesis. And if it's NULL, just make it an empty array.
[06:37 - 06:38] There we have it. We have our list.
[06:39 - 06:41] Let me open the networking tab. There we go.
[06:42 - 06:55] Another way that I like to do is wrap it around an ngIf, let me create an if and then pass our products to the products component like this. As you can see, there we have it.
[06:56 - 07:15] What we have done so far is we have rewritten our subscribe, unsubscribe boilerplate into a simple async pipe. And we've also had a look at different types of observables and why unsubscribing from your observable even though it's a finite one is always a good idea.
This lesson preview is part of the Mastering RxJS: A Compact Journey from Beginner to Pro course and can be unlocked immediately with a \newline Pro subscription or a single-time purchase. Already have access to this course? Log in here.
Get unlimited access to Mastering RxJS: A Compact Journey from Beginner to Pro, plus 70+ \newline books, guides and courses with the \newline Pro subscription.
![Thumbnail for the \newline course Mastering RxJS: A Compact Journey from Beginner to Pro](/_next/image?url=https%3A%2F%2Fs3.amazonaws.com%2Fassets.fullstack.io%2Fn%2F20240206123825301_twitter.jpg&w=3840&q=75)
Welcome back. In the previous lesson, I emphasized the importance of always unsubscribing from a subscription. Well, about that. I have to confess, I lied. There are some use cases when you don't have to unsubscribe from a subscription You will also hear from other people that you don't have to unsubscribe from HTTP calls. Let me explain. I will draw two data streams in here. The first one is a finite stream and the second one is an infinite stream. A finite stream of data is a conceptualization of an observable that emits only zero or one value. So when we subscribe to our observable, we expect either to get nothing or only one value. After we get nothing or one value, the observable will complete. And what happens after an observable completes, it will automatically unsubscribe from all its observers. This is why people say that you don't have to unsubscribe from the HTTP client because it is a finite observable. Now, an infinite observable does the same thing with the exception that it will emit an infinite amount of times. The only way for it to complete is if we manually unsubscribe from it. Infinite observables are usually events such as a mouse click or whenever we type into an input field in a form, we get new events emitted. Now, the HTTP client will clean itself up. So we don't have to worry about unsubscribing, until we do have to worry about unsubscribing. And this is the case when we have side effects. For example, let's say we have a user form in here. What this form does it will ask the user is logging credentials and after filling those in, the user will click on login, request will be sent to the server. And let's say we have a really, really slow server. The user gets bored and he decides to navigate away from the login form. That's fine. And the user is expecting that he didn't log in. Now, because we subscribed inside this form, the subscribe handler will run eventually, even though the user navigated away from it, because our observable will eventually complete. As you remember, it's a finite observable. So it can either have zero results or one. So in case of zero results, it means it will error. And let's assume we have an error handler and we want to display a notification to the user. Our user is already on another page and he assumes that he is not logged in. And suddenly he gets a notification. This will raise some eyebrows and the user will not know what actually happened in there. It will be at least confusing for the user. This is not too bad. It's only bad user experience, but in reality, nothing bad actually happened. Now let's assume we eventually get a response from the server and the server be like, hey, I finally processed your request. Here is a token. And in the subscriber handler, the token will be set in the browser. Now we have a token, even though the user is assuming he didn't log in, but we have set the token for the user in his browser. So there might be some side effects in there. Another use case is let's say, let's go back to our error scenario. Let's say we get an error message in there or a handler is handling this error. And then there is redirecting there. The user is already browsing another page is interested in something else. And suddenly he gets randomly redirected to a new page. Now, okay, this will be very confusing for the user because he definitely did not expect this to happen. As you can see, we need to be mindful and careful about it. But I think personally, it's always a good idea to unsubscribe from your observable because this way, even though you only have an HTTP call, always assume that the observable is infinite. This way you don't have to worry about unsubscribing from an observable. Now that you've seen why it's always a good idea to unsubscribe, even though some people might say otherwise, let me tell you the good news. And the good news is that there is a simpler way to handle all this boilerplate from subscribing, unsubscribing. And it's called async pipe. For those of you who do not know what a pipe is, it's basically when we have a function, the output from the left side will get passed to the output to the right side. We can do this as many times as we like it. So the output from here will go into here, then we execute this function, the output will go in here, and so forth and so forth. If you've worked with Linux or PowerShell, this is something very familiar. So let me demonstrate to you how this works in practice. The async pipe will do the subscription and unsubscription for us under the hood. So, let's remove that in here. We don't need it anymore. Let's remove the subscription as well. Let me remove that. As I promised, we don't need to subscribe anymore. The code looks much simpler, but how do we get this data from our fetch products into our product list? In here, we need to pass the observable itself to our product list in here. Let me create an observable. I'll use the same type. Now I have created this observable. By the way, when working with observables, there is a convention to annotate observables with a dollar sign. And now that I have my observable, let me assign it and let me add an exclamation mark in here. We are set up. Let me remove those unused imports. Alright, and the last thing is, let's pass our observable. Let's add the async pipe. And it's complaining because we haven't added our async pipe to the imports. We have added it. Let's save. Now it is complaining because in here for the first time, our observable is NULL. And then during ngOnInit, it gets an observable assigned to it. That's why we see it in here that the type is product list or NULL. We can fix this in different ways. The first one is to wrap it in parenthesis. And if it's NULL, just make it an empty array. There we have it. We have our list. Let me open the networking tab. There we go. Another way that I like to do is wrap it around an ngIf, let me create an if and then pass our products to the products component like this. As you can see, there we have it. What we have done so far is we have rewritten our subscribe, unsubscribe boilerplate into a simple async pipe. And we've also had a look at different types of observables and why unsubscribing from your observable even though it's a finite one is always a good idea.