Although I understand the way Angular makes HTTP requests, I prefer using the built-in Fetch API because I don't have to subscribe and unsubscribe just to make 1 simple request. I tried using it in my angular app and it didn't throw any errors, page didn't reload (still a SPA), everything worked fine. I suppose there is a time and place for everything.
This:
fetch('/api/get_post_by_id/1').then(r => r.json()).then(j => { console.log(j); });
Is more simple, than this:
const obs = this.http.get('/api'); obs.subscribe(() => { ... }); obs.unsubscribe();
Basically my question is, is it wrong to use the Fetch API when developing Angular apps?
Angular offers HttpClient to work on API and handle data easily. In this approach HttpClient along with subscribe() method will be used for fetching data.
The Fetch API is a promise-based interface for fetching resources by making HTTP requests to servers from web browsers. It is similar to XML HTTP requests but better and more powerful.
$http is an AngularJS service for reading data from remote servers.
The HttpClient is used to perform HTTP requests and it imported form @angular/common/http. The HttpClient is more modern and easy to use the alternative of HTTP. HttpClient is an improved replacement for Http. They expect to deprecate Http in Angular 5 and remove it in a later version.
Like any tool you encounter during development each tool will have advantages and disadvantages and it's good to think about why a tool is being used.
When we take a look at HttpClient
it originally simplified the mess that was XMLHttpRequest
. In the same way $.ajax
originally did it, HttpClient
was the 'angular solution'. It followed the ideology of everything being an observable which has advantages (you can mix and match it with other observables) and disadvantages (it adds a lot of bloat).
HttpClient
from
from rxjs
apiService
layer - you can still use an interceptor to achieve similar results magically.HttpClient
does some magic for you such as automatic retrying of requests.fetch
.fetch
Important : All fetch related code assumes you do create a very simple abstraction (e.g. apiService
in these examples). This is the same as setting up an interceptor in HttpClient
-land.
It's the new industry standard. Once you know it, it can be used anywhere (most likely once Angular and React die - which at some point they will - fetch
will still most likely be around).
It simplifies working with service workers as the Request
and Response
objects are the same you are using in your normal code.
HTTP requests will typically return once and only once (of course you might be loading a file chunk by chunk, but that's a very rare exception to the rule). fetch
is built around the norm (single return values), not the exception (multiple return values), and thus returns a Promise
rather than a stream-like-type. The advantage this results in is that it plays nicely with any and all relevant new language features such as async
and await
. Compare:
try { const posts = await this.apiService.get('/posts'); // work with posts } catch (error) { // handle error } console.log('this happens **after** the request completes');
with
this.http.get('/posts') .subscribe(posts => { // work with posts }) .catch(error => { // work with error }); console.log('this happens **before** the request completes');
(of course you can also toPromise
each Observable that will complete (or add .pipe(take(1))
, but that's frankly a bunch of superfluous code (which I still often end up using))
It simplifies onboarding of new people. When you see a request such as
this.apiService.get('/posts');
a developer from any framework can come and right-click on .get
and check out the function definition where things such as a domain and an authentication header being added will be clearly defined.
On the other hand when a developer sees
this.http.get('/posts')
they have no way of easily discovering if and where the request might be changed unless they are aware of Angular specific magic. This is one of the reasons why Angular is considered to have a steep learning curve.
There is no risk of there being magic you aren't aware of such as automatic retrying of requests which can end up in the same request triggering 4 times on the server and you having no idea how that's possible.
It's already included in the browser - provided you don't need to support 7 year old browsers - so it can result in a slightly smaller bundle size.
<Model>this.apiService.get('/posts')
works perfectly fine.Personally, I would strongly recommend anybody to use fetch
with an abstraction layer. It results in easier to read code (even a junior who hasn't ever seen async
and await
is able to read it) and even if you are in a rare situation where your apiService
has to return multiple times you are still completely free to do so as you're fully in control. And in general, you should only not use the standard (fetch
) if the alternative offers significant advantages. Even if it was a perfect tie in terms of advantages and disadvantages it probably isn't worth going for a 'framework specific' solution.
HttpClient
just doesn't seem to offer any tangible advantages beyond saving a couple of minutes of time during the initial project setup where you don't need to set up an abstraction layer for API requests.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With