In Angular 2, the RxJS asynchronous observables are first-class citizens and much of the core toolkit has been configured to rely upon them. Nonetheless, it is still valuable to be able to have conversion between them, especially since they have similar duties.
For more on RxJS Observables, refer to , ReactiveX Observables, which covers them in depth.
The code, links, and a live example of this are available at .
You'll begin with the following simplistic application:
[app/article.component.ts] import {Component} from '@angular/core'; import {Http} from '@angular/http'; @Component({ selector: 'article', template: ` <p></p> ` }) export class ArticleComponent { constructor(private http:Http) { // For demo purposes, have this plunk request itself to // avoid cross origin errors console.log( http.get('//run.plnkr.co/plunks/TBtcNDRelAOHDVpIuWw1')); } } // Observable {...}
Suppose your goal was to convert this HTTP call to use promises instead.
For the purposes of this recipe, you don't really need to understand any details about the http
service or RxJS asynchronous observables. All that you need to know is that any method exposed by the http
service will return an observable. Happily, the RxJS implementation can expose a .toPromise()
method that converts the observable into its equivalent Promise object:
[app/article.component.ts] import {Component} from '@angular/core'; import {Http} from '@angular/http'; import 'rxjs/Rx'; @Component({ selector: 'article', template: ` <p></p> ` }) export class ArticleComponent { constructor(private http:Http) { // For demo purposes, have this plunk request itself to // avoid cross origin errors console.log( http.get('//run.plnkr.co/plunks/TBtcNDRelAOHDVpIuWw1') .toPromise()); } } // ZoneAwarePromise {...}
The HTTP service, by default, returns an observable; however, without the imported Rx
module, this will throw an error, saying it cannot find the toPromise()
method.
The Rx
module confers to an observable the ability to convert itself into a promise object. Angular 2 is intentionally not utilizing the Observable spec with all the RxJS operators to allow you to specify exactly which ones you want. Because the operators exist as separate modules, this leads to a smaller payload sent to the browser.
Once the .toPromise()
method is invoked, the object is created to a ZoneAwarePromise
instance.
This sounds gnarly, but really, it's just wrapping the Promise
implementation as zone.js so that the Angular zone is aware of any actions the Promise could cause that it should be aware of. For your purposes, this can be treated as a regular Promise.