TetraDev
TetraDev

Reputation: 17064

Property 'do' does not exist on type 'Subscription'

What am I misunderstanding about how to use the .subscribe function in combination with the .do function?

Here is my observable sequence:

  lookupSubscriber = (text$: Observable<string>) =>

  text$.debounceTime(300)
     .distinctUntilChanged()
     .do(() => this.searching = true)
     .switchMap(term => {
        var data = this._callApi(this.lookupSubscriberAPI, term)
           .do(() => {
              this.searchFailed = false;
              this.searching = false;
           })
           .catch(() => {
              this.searchFailed = true;
              this.searching = false;
              return Observable.of([]);
           })
        return data;
     })
     .do(() => this.searching = false);

If my _callApi function is as follows, it works:

_callApi(url: string, term: string) {
  if (term === '') {
     return of.call([]);
  }

  return map.call(this.dataService.get(url + term), response => {
     var data = this._transformSubscriberInfo(response);
     return data;
  })

}

However, when I try to rewrite it with a subscribe function like this:

   _callApi = (url: string, term: string) => {

     return this.dataService.get(url + term)
        .subscribe(
           response => { this._transformSubscriberInfo(response) }, 
           error => error.text(), 
           () => {
              if (Logging.isEnabled.light) {
                 console.log('%c API Call Complete', Logging.normal.orange);
              }
        ))
}

... then the data call succeeds, but I receive error: Property 'do' does not exist on type 'Subscription'.

Basically I am trying to catch errors and run an "always" function after the api call, as shown in the second version of _callApi.

Upvotes: 1

Views: 1558

Answers (1)

Sergey Karavaev
Sergey Karavaev

Reputation: 1761

The first version of _callApi seems to return an Observable while the second one returns a Subscription object. And Subscription does not expose do, exactly as the error message states.

What you may want to try is to use a version of do that accepts error and complete callbacks in addition to the next callback:

return this.dataService.get(url + term)
    .map(response => this._transformSubscriberInfo(response))
    .do(
        response => { /* log response */ }, 
        error => { /* log error */ }, 
        () => { /* log completion */ }
    );

It worth mentioning that do is not capable of transforming the source stream, the observable it returns contains the same values as the observable it is called on. That's why we need the line .map(response => this._transformSubscriberInfo(response)).

Also complete callback should not be confused for an "always" function: it gets called only when the source observable completes and it does not get called when the observable produces an error or gets unsubscribed.

Upvotes: 4

Related Questions