Using Async Pipe & Observables
Pipes in Angular work just as pipes work in Linux. They accept an input and produce an output. What the output is going to be is determined by the pipe's functionality. This pipe accepts a promise or an observable as an input, and it can update the template whenever the promise is resolved or when the observable emits some new value. As with all pipes, we need to apply the pipe in the template.
Let's assume that we have a list of products returned by an API and that we have the following service available:
// api.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
@Injectable()
export class ApiService {
constructor(private http: HttpClient) { }
getProducts() {
return this.http.get('http://localhost:3000/api/products');
}
}
The code above is straightforward - we specify the getProducts() method that returns the HTTP GET call.
It's time to consume this service in the component. And what we'll do here is create an Observable and assign the result of the getProducts() method to it. Furthermore, we'll make that call every 1 second, so if there's an update at the API level, we can refresh the template:
// some.component.ts
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
import { ApiService } from './../api.service';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/startWith';
import 'rxjs/add/operator/switchMap';
@Component({
selector: 'app-products',
templateUrl: './products.component.html',
styleUrls: ['./products.component.css']
})
export class ProductsComponent implements OnInit {
@Input() products$: Observable<any>;
constructor(private api: ApiService) { }
ngOnInit() {
this.products$ = Observable
.interval(1000)
.startWith(0).switchMap(() => this.api.getProducts());
}
}
And last but not least, we need to apply the async pipe in our template:
<ul>
<li *ngFor="let product of products$ | async">{{ product.prod_name }} for {{ product.price | currency:'£'}}</li>
</ul>
This way, if we push a new item to the API (or remove one or multiple item(s)) the updates are going to be visible in the component in 1 second.