Yaniv Efraim
Yaniv Efraim

Reputation: 6713

Angular 2.0 - converting promise chaining to Observables

I am converting an NG 1.X service to NG 2.0.

My NG 1.X service has promise chaining (simplified):

dataService.search = function(searchExp) {
      return this.getAccessToken()
      .then(function(accesstoken) {
        var url = $interpolate('https://my-api-url?q={{search}}&{{accesstoken}}')({search: searchExp, accesstoken: accesstoken});
        return $http({
          url: url,
          method: 'GET',
          cache: true
        });
      }).then(function(response) {
        return response.data;
      });
    };

I want to convert search service to be an Angular 2.0 Service, using http and returning Observable. I prefer leaving the getAccessToken service untouched, as an NG 1.X service, which returns a promise.

I was thinking about using Observable.fromPromise on the old "promise" service.

How can I do it? How can I chain those two?

EDIT:

Just to clarify, I want it to be something like this:

dataService.search = function(searchExp) {
 return this.getAccessToken()
        .then(function(accesstoken) {
           //Here I want to use:
           // this.http.get(url).subscribe(() => ...)
          });
        };

Upvotes: 7

Views: 5449

Answers (2)

Mark Rajcok
Mark Rajcok

Reputation: 364677

I converted @dfsq's Plunker to beta.0. map() doesn't seem to be available anymore without importing it (but we don't need it here).

import {Component, Injectable} from 'angular2/core';
import {HTTP_PROVIDERS, Http} from 'angular2/http';
import {PromiseObservable} from 'rxjs/observable/fromPromise';

@Injectable()
export class DataService {
  constructor(private _http: Http, private _accessService: AccessService) {} 
  search(searchExp) {
    var promise = new Promise((resolve, reject) => {
      this._accessService.getAccessToken()  // see Plunker for AccessService
        .then(accessToken => {
          return this._http.get('data.json')  // use accessToken here
            .subscribe(res => resolve(res.json()), err => reject(err));
        });
    });
    return PromiseObservable.create(promise);
  }
}
@Component({
  selector: 'my-app',
  providers: [HTTP_PROVIDERS, AccessService, DataService],
  template: `<h2>Data loaded</h2><pre>{{data | json}}</pre>
  `
})
export class AppComponent {
  data: any;
  constructor(private _dataService: DataService) { 
    console.clear();
  } 
  ngOnInit() {
    this._dataService.search('test')
      .subscribe(res => {
        this.data = res; 
      });
  }
}

beta.0 Plunker

Upvotes: 3

dfsq
dfsq

Reputation: 193261

You should make search method return Observable object. Something like this:

dataService.search = function(searchExp) {

    var promise = new Promise((resolve, reject) => {
        this.getAccessToken()
            .then(accesstoken => {
                return this.http.get('data.json')
                    .map(response => response.json())
                    .subscribe(data => resolve(data), err => reject(err))
            })
    });

    return PromiseObservable.create(promise); // Observable.fromPromise(promise)
};

Upvotes: 8

Related Questions