3

I have a hard time to grasp the way http Observables work.

Http get always completes, when only one value arrives but there is no way to look up the implementation. Do they always complete after error or a value arrives?

I have a lot of discussion with my collegues, because the use in every http operation the following procedure:


const sub = this.http.get( enviroment.baseUrl + '/users').pipe(take(1))
                                             .subscribe( value => {
                                              //do something with the value
                                               },
                                              error => consol.log(error.message));

And later this:

ngOndestroy():void{
    sub.unsubscribe();
}

And for my understanding, pipe(take(1)) is not needed, because a http call emits always one value.

An response or a Error.

And since, a observable completes with one value, unsubscribing is not needed.

please correct me if I'm worng. I also would be pleased, to have official sources on this, if you have some in mind.

Thank you very much in advance

Luxusproblem
  • 1,913
  • 11
  • 23
  • Here is an article that might help: [Exploring the HttpClientModule in Angular](https://indepth.dev/exploring-the-httpclientmodule-in-angular/). As you can see from [here](https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts#L208-L231), they always complete after error and they also complete after the request's response has arrived. – Andrei Gătej Feb 29 '20 at 14:46
  • See: [Is it necessary to unsubscribe from observables created by Http methods?](https://stackoverflow.com/q/35042929/9423231) – frido Feb 29 '20 at 22:03

1 Answers1

10

You can read through the source code here:

HttpClient: https://github.com/angular/angular/blob/master/packages/common/http/src/client.ts

HttpXhrBackend : https://github.com/angular/angular/blob/master/packages/common/http/src/xhr.ts

In very simple terms, the pattern of all HTTP requests via the HttpClient look like this:

of(request).pipe(
  concactMap(request => this.xhr.handle(request))
);

Where request is an abstraction of an HTTP request, and this.xhr is a wrapper around javascript XHR - implemented by HttpXhrBackend.

of(request) returns a self-completing observable, so nothing to worry about there.

HttpXhrBackend.handle() executes the request using the native XHR methods. The crucial lines of code in the source are:

if (ok) {
  // A successful response is delivered on the event stream.
  observer.next(new HttpResponse({
    body,
    headers,
    status,
    statusText,
    url: url || undefined,
  }));
  // The full body has been received and delivered, no further events
  // are possible. This request is complete.
  observer.complete();
} else {
  // An unsuccessful request is delivered on the error channel.
  observer.error(new HttpErrorResponse({
    // The error in this case is the response body (error from the server).
    error: body,
    headers,
    status,
    statusText,
    url: url || undefined,
  }));
}

We can see here that the observable either completes or errors - the two ways an observable can decide its own fate.

Conclusion

Everything everyone says about not needing to unsubscribe from http requests is true - you can safely subscribe and forget.

It's not true that a request through HttpClient will only receive a single result, as you can observe other events aside from just the response.

Kurt Hamilton
  • 12,490
  • 1
  • 24
  • 40
  • The sources are very helpful. And you perfectly figured out, why I was asking. :) The whole thing about "pipe(take(1))" and "unsubscribe()". – Luxusproblem Feb 29 '20 at 17:57