In Angular, there are generally two common ways of handling and displaying data from asynchronous streams. Either use an async pipe in your template or subscribe to the observable and handle it in the callback function.
This article will explain how both methods work and compare them. We’ll do this by going through examples, making it easy for you to understand the difference between the two methods.
Sounds interesting? Then, keep on scrolling.
Display Data in Angular by Subscribing to an Observable
We’ll start by showing you an example of displaying data from an observable by subscribing to it using the subscribe
function.
Creating the Angular Service
Let’s assume we have a service containing a BehaviorSubject
handling different names. The service will also provide a function for updating the name and a function to fetch the BehaviorSubject
as an observable:
import { Injectable } from "@angular/core";
import { BehaviorSubject, Observable } from "rxjs";
@Injectable({
providedIn: "root",
})
export class NameService {
name: BehaviorSubject<string> = new BehaviorSubject("Vinnie Jones");
constructor() {}
updateName(name: string) {
this.name.next(name);
}
getName(): Observable<string> {
return this.name.asObservable();
}
}
name.service.tsThat’s all that is needed for our service.
Note: We’ll also use the same service in our other example where we use the async pipe.
Updating Our App Component
Next up, we can add the code required in our app component. We need to inject the service into our app component, we’ll do that with the help of the component’s constructor:
constructor(private name: NameService) {
name.getName().subscribe((name) => (this.currentName = name));
}
app.component.tsThen, we’ll add a function for pushing new names into our service:
pushName() {
this.name.updateName(faker.person.fullName());
}
app.component.tsAnd let’s not forget to add a property for storing the current name inside our app component:
currentName: string = "";
app.component.tsIf you’ve followed the steps properly, your app component should look something like this:
import { Component } from "@angular/core";
import { faker } from "@faker-js/faker";
import { NameService } from "./name.service";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
currentName: string = "";
constructor(private name: NameService) {
name.getName().subscribe((name) => (this.currentName = name));
}
pushName() {
this.name.updateName(faker.person.fullName());
}
}
app.component.tsNow we just have to display the name and add a button for generating new names in our HTML:
<h1>{{ currentName }}</h1>
<button mat-raised-button color="primary" (click)="pushName()">
Show me another name
</button>
app.component.htmlResult
If you now run your application, you should be able to test it out by clicking on the button and seeing the name changing:
Display Data in Angular using the Async Pipe
Let’s create the same example as the one above, but this time by using the Angular async pipe instead of subscribing to the observable.
We’ll start by removing some stuff from our app component:
import { Component } from "@angular/core";
import { faker } from "@faker-js/faker";
import { NameService } from "./name.service";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
currentName: string = ""; //REMOVE
constructor(private name: NameService) {
name.getName().subscribe((name) => (this.currentName = name)); //REMOVE
}
pushName() {
this.name.updateName(faker.person.fullName());
}
}
app.component.tsWe also need to make our injected service public and rename it to nameService
(The renaming is because name
is a reserved keyword in Typescript):
import { Component } from "@angular/core";
import { faker } from "@faker-js/faker";
import { NameService } from "./name.service";
@Component({
selector: "app-root",
templateUrl: "./app.component.html",
styleUrls: ["./app.component.scss"],
})
export class AppComponent {
constructor(public nameService: NameService) {}
pushName() {
this.nameService.updateName(faker.person.fullName());
}
}
TypeScriptNext, we can call the function getName
in the service from our HTML, using the async pipe:
<div>
<h1>{{ nameService.getName() | async }}</h1>
<button mat-raised-button color="primary" (click)="pushName()">
Show me another name
</button>
</div>
HTMLResult
As you can see, when you run the application, you get the same result as when we ran the previous example:
Async Pipe vs Subscribing to Observables
The decision on when to use the async
pipe or subscribing to an observable depends on the specific requirements and complexity of your Angular application.
Let’s go through the benefits of both methods and hopefully, you’ll know which method suits your application requirements best.
Benefits of Using the Async Pipe
- Simple Data Binding: For scenarios where you need to bind Observables directly to your template, especially when rendering data without extensive processing, the
async
pipe is a convenient choice. - Minimizing Boilerplate: When you want to reduce boilerplate code and simplify your component logic, the
async
pipe offers a cleaner and more concise solution. - Avoiding Memory Leaks: If memory management is a concern, and you want to ensure that subscriptions are automatically cleaned up, the
async
pipe is the safer option.
Benefits of Subscribing to an Observable
- Complex Data Transformation: When you need to perform complex data transformations, filtering, or combining data from multiple Observables before rendering it, subscribing to observables allows for greater flexibility and control.
- Multiple Subscriptions: If your component needs to manage multiple subscriptions and perform different actions based on the data emitted from each Observable this method may be more suitable.
- Custom Error Handling: In cases where you require custom error handling or need to perform side effects like logging, this method provides more control.
Conclusion
In conclusion, there are benefits to both using the async pipe and subscribing to an observable.
By going through the same example with both methods, we can conclude that the async pipe is recommended over subscribing to an observable if the requirement is just to show the data.
If your application has the requirements of fetching data from an observable and then transforming and calculating values dependent on the input, the subscribe method is much more suitable.
Hopefully, you enjoyed scrolling through this article. If you’re more interested in Angular, check out our other articles!