I have done quite a bit of research before deciding to post the questions here. My knowledge of how Angular (or generally) handles HTTP error is very cloudy, so I am looking for some clarification/suggestion.
To make things simple, let's say I have a rest API GET http://example.com
that will returns {error: 'Error message'}
or {data: 'Data is available'}
randomly where error
indicates something went wrong (the request completed successfully, but there is some internal error) and data
indicates that everything works fine.
Now, there are 2 things that, to my understanding, need handling. The first thing is to handling when the request fails, for example, network error, blocked by CORS, etc., and the second thing is to handle a successful request, but see if it is error
or data
.
TL;DR: How can I transform the below jQuery into Angular?
Normally, with jQuery, this is what I would do:
$.get('http://example.com').done(data => {
if ('error' in data) console.log('Request completed, but there is an error in the remote server');
else console.log('Everything completed successfully');
).fail(error => {
console.log('Error while requesting data', error);
});
Now in Angular, things get complicated and I no matter what I try, I can't seem to throw an error (all functions are properly imported):
//service.ts
getStatus() {
return this.http.get('https://test.com/')
.pipe(
map(data => {
if ('error' in data) {
//I would like to throw an error that can be caught at subscribe(done, error) later
//But this rxjs won't throw anything, subscribe() will still resolve with done()
return throwError('Request completed, but there is an error in the remote server');
}
return data;
}),
tap(data => {
//Process the data, should not be called if map() throwError()?
},
catchError(error => {
//I assume this is where the HTTP request failed due to network, CORS, etc.
return throwError('Error while requesting data');
})
);
}
//app.ts
this.service.getStatus().subscribe(data => {
//I expect this function to be called ONLY if there was no throwError(), but that wasn't the case
//No matter what I try in `service.ts`, this will always be called
}, (error) => {
//I expect this to call when throwError() is called from `service.ts` but it never happens
});
I also read another suggestion to use catch()
on subscribe()
but catch()
was never a method on a Subscription:
//app.ts
this.service.getStatus().subscribe(data => {
//I expect this function to be called ONLY if there was no throwError(), but that wasn't the case
//No matter what I try in `service.ts`, this will always be called
}).catch(error => {
//This is not valid
});
None of what I tried has worked, and there are multiple places within the pipe I can throwError()
but I'm not quite sure what their differences are (example, catchError()
in service.ts
and error
from subscribe(success, error)
in app.ts
.