The observable that HttpClient
returns usually only emits one value then completes which, on the surface seems a lot like a promise. However, the idea that it is purely for consistency and/or that promises are always eschewed in Angular isn't true. As others have noted, the async pipe supports promises as does application init. So why use observables instead of promises for http requests? Because observables offer another layer of abstraction.
In that thread you linked, this comment makes a crucial point:
@gman Exactly. The Promise simply represents some future value. It does not represent the operation which generates the value. You cannot cancel a value. You cannot retry a value. It's just a value. It may or may not be present yet, and it may never exist because an exception occurred, but that's it.
Cancellation
Let's talk about cancelling a HTTP request. In the case of the observable, HttpXhrBackend
is just one implementation of HttpBackend
and handles the cancellation of the observable by calling XMLHttpRequest.abort()
:
// This is the return from the Observable function, which is the
// request cancellation handler.
return () => {
// On a cancellation, remove all registered event listeners.
xhr.removeEventListener('error', onError);
xhr.removeEventListener('load', onLoad);
if (req.reportProgress) {
xhr.removeEventListener('progress', onDownProgress);
if (reqBody !== null && xhr.upload) {
xhr.upload.removeEventListener('progress', onUpProgress);
}
}
// Finally, abort the in-flight request.
if (xhr.readyState !== xhr.DONE) {
xhr.abort();
}
};
Note that when you're consuming this promise, you don't actually care that it's using XMLHttpRequest
and it could be using SomeWhackyAngularXMLHttpRequestThatIsBetter
. Let's say we return a promise instead:
// How would something that consumes this call xhr.abort()?
function myHttpGetPromise(method, url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onload = resolve;
xhr.onerror = reject;
xhr.send();
});
}
How could your client cancel the request with just that promise? You would have to either:
- Somehow expose the implementation (our
XMLHttpRequest
instance in this case).
- Provide your own layer of abstraction around the
XMLHttpRequest
(something like httpPromise
which supports abort) to allow for cancellation.
Re-use
Promises are not re-usable. Let's say you want to retry an HTTP request using promises. How would you do it? You guessed it: you would have to add another layer of abstraction. In the case of observables, we have retry support out of the box.
Conclusion
One thing worth mentioning in closing is that the angular HttpClient
doesn't always just return one value. In the case where you set reportProgress
to true, it emits multiple HttpEvents
before finally completing when the request is complete. See the docs for more info. And finally, you should read the original issue where this was debated in the Angular repo for some backstory.
As far as I am using Http in Angular, I agree that in the normal use cases there is not much difference when using Observable over Promise.
Please explain what are talking about http. – DornickAs far as I am using Http in Angular, I agree that in the normal use cases there is not much difference when using Observable over Promise.
Please explain what are talking about http. – Dornickswitchmap
,takeWhile
andforkjoin
is enougth in the most of cases to call an API – Buhrstone