UNPKG

5.38 kBJavaScriptView Raw
1
2import { Notify } from './Notify';
3
4export const ApiConfig = {
5 prefix: '/ajax',
6 headers: {
7 'Accept': 'application/json',
8 'X-Requested-With': 'XMLHttpRequest',
9 },
10 credentials: 'same-origin', // fetch Request credential option to send cookies
11 redirectDelay: 2000, // if server returned data.redirect, redirect to that URL after redirectDelay ms.
12};
13
14export const Api = {
15
16 Config: ApiConfig,
17
18 prefix: '',
19
20 request(url, method = 'GET', body = null, additionalHeaders = {}, responseType = 'json', useGlobalHeaders = true) {
21 const req = this.createRequest(url, method, body, additionalHeaders, responseType, useGlobalHeaders);
22 return fetch(req).then(response => {
23 if (response.status === 200) {
24 return response[responseType]();
25 } else {
26 return this.onStatusFail(response);
27 }
28 }).then(data => {
29 return this.onResponse(data);
30 }).catch(response => {
31 return this.onError(response, this.createUrl(url), method);
32 });
33 },
34
35 createRequest(url, method = 'GET', body = null, additionalHeaders = {}, responseType = 'json', useGlobalHeaders = true) {
36 const headers = this.createHeaders(additionalHeaders, useGlobalHeaders);
37 const initObj = {method, headers, credentials: this.Config.credentials};
38 if (body !== null) {
39 initObj.body = body;
40 }
41 return new Request(this.createUrl(url), initObj);
42 },
43
44 createHeaders(additionalHeaders = {}, useGlobalHeaders = true) {
45 let headers = {};
46 if (useGlobalHeaders) {
47 headers = Object.assign({}, this.Config.headers, additionalHeaders);
48 } else {
49 headers = additionalHeaders;
50 }
51 return new Headers(headers);
52 },
53
54 createUrl(url) {
55 return url.indexOf('://') > -1 ? url : this.Config.prefix + this.prefix + url;
56 },
57
58 get(url, params = null, additionalHeaders = {}) {
59 let queryStr = '';
60 if (params !== null) {
61 queryStr = '?' + Object.keys(params)
62 .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
63 .join('&');
64 }
65 return this.request(url + queryStr, 'GET', null, additionalHeaders);
66 },
67
68 createFormData(data) {
69 if (data instanceof FormData) {
70 return data;
71 }
72 const formData = new FormData();
73 for (let key in data) {
74 formData.append(key, data[key]);
75 }
76 return formData;
77 },
78
79 post(url, data, additionalHeaders = {}) {
80 return this.request(url, 'POST', this.createFormData(data), additionalHeaders);
81 },
82
83 // data is root object returned by server and not just inner data key
84 onResponse(data) {
85 if (data.message) {
86 this.showStatusWarning(data.message);
87 } else if (data.success) {
88 this.showStatusSuccess(data.success);
89 }
90 this.attemptRedirect(data);
91 return data;
92 },
93
94 onError(response, url, method) {
95 const error = response.status + ' (' + response.statusText + ')';
96 console.error('Api call error:\n URL: ' + url + '\n Method: ' + method + '\n Status: ' + error);
97 return Promise.reject(response);
98 },
99
100 onRequestEntityTooLarge() {
101 this.showStatusError('413: Request entity too large!');
102 },
103
104 onStatusNotFound() {
105 this.showStatusError('404: API Route not found!');
106 },
107
108 onStatusAccessDenied() {
109 this.showStatusError('403: Access denied!');
110 },
111
112 onStatusUnauthorized() {
113 this.showStatusError('401: You are not logged in!');
114 },
115
116 onStatusServerError() {
117 this.showStatusError('500: Server error!');
118 },
119
120 onStatusFail(response) {
121 const status = response.status;
122 const methodName = 'onStatus' + status;
123 if (this[methodName] !== undefined) {
124 this[methodName](response);
125 } else if (status === 413) {
126 this.onRequestEntityTooLarge();
127 } else if (status === 404) {
128 this.onStatusNotFound();
129 } else if (status === 403) {
130 this.onStatusAccessDenied();
131 } else if (status === 401) {
132 this.onStatusUnauthorized();
133 } else if (status === 500) {
134 this.onStatusServerError();
135 }
136 return Promise.reject(response);
137 },
138
139 showStatusError(message, autoRemoveAfter = Notify.Config.autoRemoveAfter) {
140 Notify.danger(message, autoRemoveAfter);
141 },
142
143 showStatusWarning(message, autoRemoveAfter = Notify.Config.autoRemoveAfter) {
144 Notify.warning(message, autoRemoveAfter);
145 },
146
147 showStatusSuccess(message, autoRemoveAfter = Notify.Config.autoRemoveAfter) {
148 Notify.success(message, autoRemoveAfter);
149 },
150
151 // for redirect back in browser history, server should provide redirectback key
152 // if redirect back in browser was not possible, will refresh page or if redirect key was provided as well, redirect to it instead
153 // othwerwise refreshes page if redirect key is provided and is empty string or redirects to provided URL
154 attemptRedirect(data) {
155 let f = null;
156 if (data.redirectback !== undefined) {
157 if (document.referrer !== '') {
158 f = () => {location.href = document.referrer}
159 } else if (data.redirect === undefined || data.redirect === '') {
160 f = () => location.reload();
161 } else {
162 f = () => {location.href = data.redirect}
163 }
164 } else if (data.redirect !== undefined) {
165 if (data.redirect === '') {
166 f = () => location.reload();
167 } else {
168 f = () => {location.href = data.redirect}
169 }
170 }
171 if (f!== null) {
172 setTimeout(f, this.Config.redirectDelay);
173 }
174 },
175
176};