3 * Perform a HTTP GET request.
4 * Can easily pass query parameters as the second parameter.
6 * @param {Object} params
7 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
9 async function get(url, params = {}) {
17 * Perform a HTTP POST request.
19 * @param {Object} data
20 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
22 async function post(url, data = null) {
23 return dataRequest('POST', url, data);
27 * Perform a HTTP PUT request.
29 * @param {Object} data
30 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
32 async function put(url, data = null) {
33 return dataRequest('PUT', url, data);
37 * Perform a HTTP PATCH request.
39 * @param {Object} data
40 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
42 async function patch(url, data = null) {
43 return dataRequest('PATCH', url, data);
47 * Perform a HTTP DELETE request.
49 * @param {Object} data
50 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
52 async function performDelete(url, data = null) {
53 return dataRequest('DELETE', url, data);
57 * Perform a HTTP request to the back-end that includes data in the body.
58 * Parses the body to JSON if an object, setting the correct headers.
59 * @param {String} method
61 * @param {Object} data
62 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
64 async function dataRequest(method, url, data = null) {
70 if (typeof data === 'object' && !(data instanceof FormData)) {
71 options.headers = {'Content-Type': 'application/json'};
72 options.body = JSON.stringify(data);
75 return request(url, options)
79 * Create a new HTTP request, setting the required CSRF information
80 * to communicate with the back-end. Parses & formats the response.
82 * @param {Object} options
83 * @returns {Promise<{headers: Headers, original: Response, data: (Object|String), redirected: boolean, statusText: string, url: string, status: number}>}
85 async function request(url, options = {}) {
86 if (!url.startsWith('http')) {
87 url = window.baseUrl(url);
91 const urlObj = new URL(url);
92 for (let paramName of Object.keys(options.params)) {
93 const value = options.params[paramName];
94 if (typeof value !== 'undefined' && value !== null) {
95 urlObj.searchParams.set(paramName, value);
98 url = urlObj.toString();
101 const csrfToken = document.querySelector('meta[name=token]').getAttribute('content');
102 options = Object.assign({}, options, {
103 'credentials': 'same-origin',
105 options.headers = Object.assign({}, options.headers || {}, {
106 'baseURL': window.baseUrl(''),
107 'X-CSRF-TOKEN': csrfToken,
110 const response = await fetch(url, options);
111 const content = await getResponseContent(response);
114 headers: response.headers,
115 redirected: response.redirected,
116 status: response.status,
117 statusText: response.statusText,
124 * Get the content from a fetch response.
125 * Checks the content-type header to determine the format.
127 * @returns {Promise<Object|String>}
129 async function getResponseContent(response) {
130 const responseContentType = response.headers.get('Content-Type');
131 const subType = responseContentType.split('/').pop();
133 if (subType === 'javascript' || subType === 'json') {
134 return await response.json();
137 return await response.text();
145 delete: performDelete,