The Async Pipe in Angular 2 can reduce boilerplate and mental overhead when dealing with observables and promises. This lesson explores how the Async Pipe works, the code it eliminates, and demonstrates common use-cases within your applications!
The async pipe can reduce both boilerplate and metal overhead when dealing with observables and promises in angular two. Let's see how we can put it to use. Start by creating an observable and applying the interval operator to emit a value every one second.
To begin receiving values, we need to call subscribe. And we're just going to take all emitted numbers and assign it to a local property. So let's create that now. We'll call it "count." And for every emitted number, we're just going to go ahead and assign it to count.
We can now add this to our template to make sure it's working. So we'll just create a basic header and print out the contents of count. As you can see, all we're really doing is creating a local property to take whatever comes out of our observable and store it for display in our view. So it would be nice if we could actually get rid of this subscribe block here and have this happen automatically for us.
There's also an issue that's not as apparent from a surface level but can cause problems in our application, and that's the need to properly dispose of our subscriptions. So let's set a console log in our subscribe block here and print out the emitted values of our observable. So our sample application just has two views. And you'll see as we switch and come back, we're still getting the emitted values from the first subscription. And we have a new subscription.
And now we have three subscriptions going and three observables emitting values, which is definitely not the behavior we're looking for. So one way to address this problem is to come over to our component and we'll create a subscription property.
And when we call subscribe on an observable, it returns a subscription which has an unsubscribe method. So using the angular two lifecycle hooks, we can implement an NG on destroy method which will be called "whenever our component is destroyed." And here we'll just call unsubscribe on our subscription.
So let's see how this works now. So we'll come over and switch views to our demo view, come back, switch a couple times. And we'll see that we still only have one subscription, so it's working as intended at this point. But we end up with quite a bit of boilerplate for just a single observable subscription.
So we're having to store reference to this subscription locally. We need to remember to call unsubscribe on NG on destroy. What if we could remove all this and just have this handle for us in our template? And that's what the async pipe can do for us.
So we'll get rid of our subscription reference, get rid of our subscribe block. Instead, create a counter property that is just the observable itself. We can also remove this subscription here and come up to our template. And now we'll pipe our observable through the async pipe. This does a couple things for us. It'll subscribe to our observable. It will keep track of the last emitted value and trigger change detection when necessary.
And it will also call unsubscribe when NG on destroy is evoked. So to test that, let's add a logger to our interval. And we can come over and start switching views. So we'll go to demo view. We'll go back to our async pipe view. And we'll see we still just have one subscription, so the async pipe is handling the disposal of subscriptions for us.
Now that we've seen how the async pipe works with observables, let's look at some common use cases. So imagine we want to display on the screen whenever a number a minute from our counter observable was even. So let's just map the numbers from the counter to a true or false based on whether they're even or odd. We can now use our evens observable inside the NG if trick just like it was a normal property utilizing the async pipe.
So on refresh we'll see that we now get even when the count is even and it disappears when it's odd. We can also easily handle observables that emit arrays or objects. So let's go ahead and create an example of each now. And we'll add it to our template.
You can see the information is now displaying correctly. So what we've done is create a people observable that just emits an array of people and a person observable that just emits a single object delayed by three seconds. We can use NG four as normal, utilizing the async pipe for our people observable.
Objects are slightly different as we surround the observable and async pipe and prints. We can then access properties off that emitted value. It's a good idea to use the Elvis operator here to prevent errors when these values arrive after the view has already been initialized. So in our case we're delaying by three seconds. So without this we would receive an error trying to access a property on an object that's undefined.
The async pipe also works on promises. To see this in action, let's create a method "get data" that returns a promise that resolves after five seconds. We can now invoke this method when our constructor is called. Let's fix up our template to display the data received from the promise.
All that's left to do is apply the async pipe. And when the promise from the get data resolves, the data is correctly displayed in our template. Behind the scenes, the async pipe checks to see whether the input is a promise or observable and correctly calls then or subscribe assigning the emitted or received values. And that is the async pipe and angular two.