jellyfish-web/src/components/fetchhelper.js
2020-06-06 11:25:53 +02:00

117 lines
3.5 KiB
JavaScript

/* eslint-disable indent */
export function getFetchPromise(request) {
const headers = request.headers || {};
if (request.dataType === 'json') {
headers.accept = 'application/json';
}
const fetchRequest = {
headers: headers,
method: request.type,
credentials: 'same-origin'
};
let contentType = request.contentType;
if (request.data) {
if (typeof request.data === 'string') {
fetchRequest.body = request.data;
} else {
fetchRequest.body = paramsToString(request.data);
contentType = contentType || 'application/x-www-form-urlencoded; charset=UTF-8';
}
}
if (contentType) {
headers['Content-Type'] = contentType;
}
let url = request.url;
if (request.query) {
const paramString = paramsToString(request.query);
if (paramString) {
url += `?${paramString}`;
}
}
if (!request.timeout) {
return fetch(url, fetchRequest);
}
return fetchWithTimeout(url, fetchRequest, request.timeout);
}
function fetchWithTimeout(url, options, timeoutMs) {
console.debug(`fetchWithTimeout: timeoutMs: ${timeoutMs}, url: ${url}`);
return new Promise(function (resolve, reject) {
const timeout = setTimeout(reject, timeoutMs);
options = options || {};
options.credentials = 'same-origin';
fetch(url, options).then(function (response) {
clearTimeout(timeout);
console.debug(`fetchWithTimeout: succeeded connecting to url: ${url}`);
resolve(response);
}, function (error) {
clearTimeout(timeout);
console.debug(`fetchWithTimeout: timed out connecting to url: ${url}`);
reject(error);
});
});
}
/**
* @param params {Record<string, string | number | boolean>}
* @returns {string} Query string
*/
function paramsToString(params) {
return Object.entries(params)
// eslint-disable-next-line no-unused-vars
.filter(([_, v]) => v !== null && v !== undefined)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&');
}
export function ajax(request) {
if (!request) {
throw new Error('Request cannot be null');
}
request.headers = request.headers || {};
console.debug(`requesting url: ${request.url}`);
return getFetchPromise(request).then(function (response) {
console.debug(`response status: ${response.status}, url: ${request.url}`);
if (response.status < 400) {
if (request.dataType === 'json' || request.headers.accept === 'application/json') {
return response.json();
} else if (request.dataType === 'text' || (response.headers.get('Content-Type') || '').toLowerCase().startsWith('text/')) {
return response.text();
} else {
return response;
}
} else {
return Promise.reject(response);
}
}, function (err) {
console.error(`request failed to url: ${request.url}`);
throw err;
});
}
/* eslint-enable indent */