/**
- * Perform a HTTP GET request.
- * Can easily pass query parameters as the second parameter.
- * @param {String} url
- * @param {Object} params
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
+ * @typedef FormattedResponse
+ * @property {Headers} headers
+ * @property {Response} original
+ * @property {Object|String} data
+ * @property {Boolean} redirected
+ * @property {Number} status
+ * @property {string} statusText
+ * @property {string} url
*/
-async function get(url, params = {}) {
- return request(url, {
- method: 'GET',
- params,
- });
-}
/**
- * Perform a HTTP POST request.
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
+ * Get the content from a fetch response.
+ * Checks the content-type header to determine the format.
+ * @param {Response} response
+ * @returns {Promise<Object|String>}
*/
-async function post(url, data = null) {
- return dataRequest('POST', url, data);
-}
+async function getResponseContent(response) {
+ if (response.status === 204) {
+ return null;
+ }
-/**
- * Perform a HTTP PUT request.
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
- */
-async function put(url, data = null) {
- return dataRequest('PUT', url, data);
-}
+ const responseContentType = response.headers.get('Content-Type') || '';
+ const subType = responseContentType.split(';')[0].split('/').pop();
-/**
- * Perform a HTTP PATCH request.
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
- */
-async function patch(url, data = null) {
- return dataRequest('PATCH', url, data);
-}
+ if (subType === 'javascript' || subType === 'json') {
+ return response.json();
+ }
-/**
- * Perform a HTTP DELETE request.
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
- */
-async function performDelete(url, data = null) {
- return dataRequest('DELETE', url, data);
+ return response.text();
}
-/**
- * Perform a HTTP request to the back-end that includes data in the body.
- * Parses the body to JSON if an object, setting the correct headers.
- * @param {String} method
- * @param {String} url
- * @param {Object} data
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
- */
-async function dataRequest(method, url, data = null) {
- const options = {
- method,
- body: data,
- };
+export class HttpError extends Error {
- // Send data as JSON if a plain object
- if (typeof data === 'object' && !(data instanceof FormData)) {
- options.headers = {
- 'Content-Type': 'application/json',
- 'X-Requested-With': 'XMLHttpRequest',
- };
- options.body = JSON.stringify(data);
- }
-
- // Ensure FormData instances are sent over POST
- // Since Laravel does not read multipart/form-data from other types
- // of request. Hence the addition of the magic _method value.
- if (data instanceof FormData && method !== 'post') {
- data.append('_method', method);
- options.method = 'post';
+ constructor(response, content) {
+ super(response.statusText);
+ this.data = content;
+ this.headers = response.headers;
+ this.redirected = response.redirected;
+ this.status = response.status;
+ this.statusText = response.statusText;
+ this.url = response.url;
+ this.original = response;
}
- return request(url, options);
}
/**
* to communicate with the back-end. Parses & formats the response.
* @param {String} url
* @param {Object} options
- * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
+ * @returns {Promise<FormattedResponse>}
*/
async function request(url, options = {}) {
- if (!url.startsWith('http')) {
- url = window.baseUrl(url);
+ let requestUrl = url;
+
+ if (!requestUrl.startsWith('http')) {
+ requestUrl = window.baseUrl(requestUrl);
}
if (options.params) {
- const urlObj = new URL(url);
+ const urlObj = new URL(requestUrl);
for (const paramName of Object.keys(options.params)) {
const value = options.params[paramName];
if (typeof value !== 'undefined' && value !== null) {
urlObj.searchParams.set(paramName, value);
}
}
- url = urlObj.toString();
+ requestUrl = urlObj.toString();
}
const csrfToken = document.querySelector('meta[name=token]').getAttribute('content');
- options = {...options, credentials: 'same-origin'};
- options.headers = {
- ...options.headers || {},
+ const requestOptions = {...options, credentials: 'same-origin'};
+ requestOptions.headers = {
+ ...requestOptions.headers || {},
baseURL: window.baseUrl(''),
'X-CSRF-TOKEN': csrfToken,
};
- const response = await fetch(url, options);
+ const response = await fetch(requestUrl, requestOptions);
const content = await getResponseContent(response);
const returnData = {
data: content,
}
/**
- * Get the content from a fetch response.
- * Checks the content-type header to determine the format.
- * @param {Response} response
- * @returns {Promise<Object|String>}
+ * Perform a HTTP request to the back-end that includes data in the body.
+ * Parses the body to JSON if an object, setting the correct headers.
+ * @param {String} method
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
*/
-async function getResponseContent(response) {
- if (response.status === 204) {
- return null;
- }
+async function dataRequest(method, url, data = null) {
+ const options = {
+ method,
+ body: data,
+ };
- const responseContentType = response.headers.get('Content-Type') || '';
- const subType = responseContentType.split(';')[0].split('/').pop();
+ // Send data as JSON if a plain object
+ if (typeof data === 'object' && !(data instanceof FormData)) {
+ options.headers = {
+ 'Content-Type': 'application/json',
+ 'X-Requested-With': 'XMLHttpRequest',
+ };
+ options.body = JSON.stringify(data);
+ }
- if (subType === 'javascript' || subType === 'json') {
- return await response.json();
+ // Ensure FormData instances are sent over POST
+ // Since Laravel does not read multipart/form-data from other types
+ // of request. Hence the addition of the magic _method value.
+ if (data instanceof FormData && method !== 'post') {
+ data.append('_method', method);
+ options.method = 'post';
}
- return await response.text();
+ return request(url, options);
+}
+
+/**
+ * Perform a HTTP GET request.
+ * Can easily pass query parameters as the second parameter.
+ * @param {String} url
+ * @param {Object} params
+ * @returns {Promise<FormattedResponse>}
+ */
+export async function get(url, params = {}) {
+ return request(url, {
+ method: 'GET',
+ params,
+ });
+}
+
+/**
+ * Perform a HTTP POST request.
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
+ */
+export async function post(url, data = null) {
+ return dataRequest('POST', url, data);
}
-class HttpError extends Error {
+/**
+ * Perform a HTTP PUT request.
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
+ */
+export async function put(url, data = null) {
+ return dataRequest('PUT', url, data);
+}
- constructor(response, content) {
- super(response.statusText);
- this.data = content;
- this.headers = response.headers;
- this.redirected = response.redirected;
- this.status = response.status;
- this.statusText = response.statusText;
- this.url = response.url;
- this.original = response;
- }
+/**
+ * Perform a HTTP PATCH request.
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
+ */
+export async function patch(url, data = null) {
+ return dataRequest('PATCH', url, data);
+}
+/**
+ * Perform a HTTP DELETE request.
+ * @param {String} url
+ * @param {Object} data
+ * @returns {Promise<FormattedResponse>}
+ */
+async function performDelete(url, data = null) {
+ return dataRequest('DELETE', url, data);
}
-export default {
- get,
- post,
- put,
- patch,
- delete: performDelete,
- HttpError,
-};
+export {performDelete as delete};