Fetch is the “de facto” standard now if building a new javascript code. Even if not yet supported by all browsers it is warmly recommended. There are numerous examples of usage but after reading a lot of them most of them seemed to miss the answer to my questions. These where:
- how to proper do error handling including having a default error handler which can be overriden
- how to do http POST?
- how to use in real-life application? I mean one would expect to do a fetch for a login api and then all other api to work (i.e. have cookie support).
The following code (typescript) will try to answer the above questions:
<pre lang="javascript">function myFetch(path: string, params: Object, customCatch: boolean = false): Promise {
let requestParams: RequestInit = {
mode: 'cors',
cache: 'default',
credentials: 'include' //this is REQUIRED to enable cookie management
};
requestParams.body = $.params(object); //generate a query string: 'param1=val¶m2=val';
requestParams.headers = {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8" //this is REQUIRED for POST with this payload
};
requestParams.method = 'POST';
return fetch(path, requestParams)
.then(response => {
if (response.ok) {
return response.text();
} else {
throw (response);
}
})
.catch(err => {
//please note that "TYPEERROR: FAILED TO FETCH" is a very BAD error message. From the spec:
//"A fetch() promise will reject with a TypeError when a network error is encountered,
//although this usually means permission issues or similar"
if (customCatch) {
//this allows to override error handler with a custom function
throw (err);
} else {
if (err instanceof Response) { //server error code, thrown from else above
//handle this error
} else { //this is network error
//handle this error
}
}
return null;
});
}
//fetch with default error handling
myFetch('/api', {user: 'toto', task: 'info'})
.then(
response => {
if(response != null){
//handle response
}
});
//fetch with custom error handling
myFetch('/api', {user: 'toto', task: 'info'}, true)
.then(
response => {
if(response != null){
//handle response
}
})
.catch(errResponse => {
//handler errResponse (both error status and network error)
})