1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
import Overlay from './overlay.js';
class AbstractAPI
{
static get supportedMethods() {
return ['GET', 'HEAD', 'POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE'];
}
// Helper function that normalizes options
static adjustOptions (options = {}) {
return Object.assign({}, {
method: 'get',
parameters: {},
headers: {},
data: {},
overlay: false,
async: false,
before: false
}, options || {});
}
constructor (base_url) {
if (this.constructor === AbstractAPI) {
throw new TypeError('You should not instantiate the abstract api');
}
this.total_requests = 0;
this.request_count = 0;
this.queue = [];
this.base_url = base_url;
}
encodeData (data, method) {
if (data instanceof Function) {
data = data();
}
return data;
}
request (url, options = {}) {
// Normalize parameters
if (Array.isArray(url)) {
// Remove empty trailing chunks
while (url[url.length - 1] === '') {
delete url[url.length - 1];
}
// Convert array to string
url = url.join('/');
}
options = this.constructor.adjustOptions(options);
var deferred;
if (options.async && this.request_count > 0) {
// Request should be sent asynchronous after every other request
// is finished. The configuration for this particular request is
// stored in a deferred which is then queued for execution.
deferred = $.Deferred();
deferred.then(() => this.request(url, options));
this.queue.push(deferred);
} else if (options.before instanceof Function && !options.before()) {
// A before function was defined and returned false, so the request
// is canceled
deferred = $.Deferred((dfd) => dfd.reject());
} else {
// Increase request counters, show overlay if neccessary
if (this.request_count === 0 && options.overlay) {
Overlay.show(true, null, true);
}
this.request_count += 1;
this.total_requests += 1;
// Actual request
deferred = $.ajax(STUDIP.URLHelper.getURL(`${this.base_url}/${url}`, {}, true), {
contentType: options.contentType || 'application/x-www-form-urlencoded; charset=UTF-8',
method: options.method.toUpperCase(),
data: this.encodeData(options.data, options.method.toUpperCase()),
headers: options.headers
}).always(() => {
// Decrease request counter, remove overlay if neccessary
this.request_count -= 1;
if (this.request_count === 0 && options.overlay) {
Overlay.hide();
}
});
}
return deferred.always(() => {
// Check if any request was queued
if (this.request_count === 0 && this.queue.length > 0) {
this.queue.shift().resolve();
}
}).promise();
}
}
// Create shortcut methods for easier access by method
AbstractAPI.supportedMethods.forEach((method) => {
AbstractAPI.prototype[method] = function (url, options = {}) {
options = this.constructor.adjustOptions(options);
options.method = method;
return this.request.call(this, url, options);
};
});
export default AbstractAPI;
|