Skip to content

Instantly share code, notes, and snippets.

@matheusb-comp
Last active February 16, 2021 16:54
Show Gist options
  • Save matheusb-comp/040183787c587fb9b65bd6853c9afe28 to your computer and use it in GitHub Desktop.
Save matheusb-comp/040183787c587fb9b65bd6853c9afe28 to your computer and use it in GitHub Desktop.
Simple fetch wrapper to select the proper function to use when processing the response. Also rejects if HTTP code is not in the range 200-299
/**
* Reads the entire response body and process based in the Content-Type header
* https://developer.mozilla.org/en-US/docs/Web/API/Body
*
* @param {object} response A response from a fetch request
* @param {boolean} arrayBuffer When body can't be processed to `text`,
* `json`, or `form-data`, process it to an ArrayBuffer or a Blob (default)
*
* @return {Promise} A promise that resolves after the entire body is processed
*/
function processBody(response, arrayBuffer = false) {
const mime = (response.headers.get('Content-Type') || '').split(',')[0]
if (mime.includes('text')) return response.text()
else if (mime.includes('json')) return response.json()
else if (mime.includes('form-data')) return response.formData()
else return (arrayBuffer) ? response.arrayBuffer() : response.blob()
}
/**
* Requests a resource using fetch, and process the response body by default
*
* @param {string} resource URL of a network resource
* @param {object} options Fetch request options object
* @param {boolean} readBody Read and process the entire response body
* @param {boolean} arrayBuffer When body can't be processed to `text`,
* `json`, or `form-data`, process it to an ArrayBuffer or a Blob (default)
*
* @return {Promise} A promise that resolves when the request is succesful
* (HTTP status code between 200 and 299) and rejects otherwise.
* Errors are similar to the Axios library, with `error.response` (HTTP errors)
* and `error.message` (failed to fetch / cancelled requests)
*/
function request(resource, options, readBody = true, arrayBuffer = false) {
return new Promise((resolve, reject) => {
const config = { resource, ...options }
fetch(resource, options)
// Reject if not ok (HTTP status not in the range 200-299)
.then((response) => {
const message = 'Request failed'
const res = { response, config }
// If requested, read and process the entire response body
if (readBody) processBody(response, arrayBuffer).then((data) => {
return (response.ok)
? resolve({ ...res, data })
: reject({ ...res, data, message })
})
else (response.ok) ? resolve(res) : reject({ ...res, message })
})
// Network/Cancel errors, similar to the error handling in Axios
.catch((error) => reject({ message: error.message, config }))
})
}
export default request
function getCookie(name) {
if (document.cookie && RegExp) {
var match = document.cookie.match(new RegExp(`${name}=([^;]+)`));
if (match && match.length > 0) return match[1];
}
return '';
}
var formData = new FormData();
for (i of [1, 2, 3]) {
var b = new Blob([Math.random()]);
formData.append('files[]', new File([b], `name-${i}`));
}
console.log('files[]:', formData.getAll('files[]'));
fetch('/upload-files', {
method: 'POST',
headers: { 'X-Xsrf-Token': decodeURIComponent(getCookie('XSRF-TOKEN')) },
body: formData,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment