As you already know Angular2 introduced RxJs Library in the new version of Angular, and I will show you how you can use it on HTTP service.
Angular1 uses Promises to manage async data, Observable are similar, but the difference is that Observables emit multiple values over time, cancel-able and can use Array#extras like operations (LINQ), whereas Promise once called will always return one value or one error.
First we create our data:
{"data": [ {"id": 1, "name": "Cafe Come", "city_id":1}, {"id": 2, "name": "Cafe Beirut", "city_id":2}, {"id": 3, "name": "Cafe Twister", "city_id":3}, {"id": 4, "name": "Cafe Volano", "city_id":4}, {"id": 5, "name": "Cafe Casual", "city_id":2} ]}
Next, we create a new Service class, and initialize a new Subject in the constructor, so our components can subscribe to it, and we create an interface for our data type ILounge.
export interface ILounge { id: number; name: String; city_id: number; } @Injectable() export class LoungeService { public subject$: Subject<ILounge[]>;
private lounges:ILounge[]; constructor(private http:Http){
this.subject$ = new Subject();
} }
In our lounge service we have a private data store, this is where we store our list of lounges in memory. You also notice the dollar-sign on our subject object, this is common practice to indicate this is Observable.
Let’s define getLoungesByCity method to load our json document and return only the specific lounges for the component.
filterLoungesByCity(city:ICity) { return this.lounges.filter((lounge) => lounge.city_id === city.id); } getLoungesByCity(city:ICity) { if (this.lounges !== undefined) { this.subject$.next(this.filterLoungesByCity(city)); } else { this.http.get(“lounges.json”).map(res => res.json().data).subscribe({next: (data) => { this.lounges = data; this.subject$.next(this.filterLoungesByCity(city)); }, error: (error) => console.log(error)}); } }
Instead of getLoungesByCity method returning new values of our lounges list, they update our internal data store, and then use Subject to push new values down our data stream, this is done using next() method on the subject.
this.subject$.next(this.filterLoungesByCity(city));
Our filterLoungesByCity will filter only the specific data the component is only interested in.
Last we will have another method getLoungeByCity which will push only one lounge to our component, in case we only interested in a specific lounge.
getLoungeByCity(city:ICity) { this.subject$.next(this.filterLoungesByCity(city)); }
Let’s take a look at how we would use the new LoungeService we just created to display a list of lounges based on the City we are visiting:
@Component({ selector: 'lounge-list', directives: [LoungeItemComponent], template: ` <ul> <lounge-item *ngFor="#lounge of lounges" [lounge]="lounge"></lounge-item> </ul> `, }) export class LoungeListComponent implements ngOnInit { public lounges:ILounge[]; @Input() city:ICity; constructor(private loungeService:LoungeService) {} ngOnInit() { this.loungeService.subject$.subscribe((lounges) => { this.lounges = lounges; }); this.loungeService.getLoungesByCity(this.city); } }