summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/lib/utils/ajax_cache.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/lib/utils/ajax_cache.js')
-rw-r--r--app/assets/javascripts/lib/utils/ajax_cache.js54
1 files changed, 54 insertions, 0 deletions
diff --git a/app/assets/javascripts/lib/utils/ajax_cache.js b/app/assets/javascripts/lib/utils/ajax_cache.js
new file mode 100644
index 00000000000..cf030d613df
--- /dev/null
+++ b/app/assets/javascripts/lib/utils/ajax_cache.js
@@ -0,0 +1,54 @@
+class AjaxCache {
+ constructor() {
+ this.internalStorage = { };
+ this.pendingRequests = { };
+ }
+
+ get(endpoint) {
+ return this.internalStorage[endpoint];
+ }
+
+ hasData(endpoint) {
+ return Object.prototype.hasOwnProperty.call(this.internalStorage, endpoint);
+ }
+
+ remove(endpoint) {
+ delete this.internalStorage[endpoint];
+ }
+
+ retrieve(endpoint) {
+ if (this.hasData(endpoint)) {
+ return Promise.resolve(this.get(endpoint));
+ }
+
+ let pendingRequest = this.pendingRequests[endpoint];
+
+ if (!pendingRequest) {
+ pendingRequest = new Promise((resolve, reject) => {
+ // jQuery 2 is not Promises/A+ compatible (missing catch)
+ $.ajax(endpoint) // eslint-disable-line promise/catch-or-return
+ .then(data => resolve(data),
+ (jqXHR, textStatus, errorThrown) => {
+ const error = new Error(`${endpoint}: ${errorThrown}`);
+ error.textStatus = textStatus;
+ reject(error);
+ },
+ );
+ })
+ .then((data) => {
+ this.internalStorage[endpoint] = data;
+ delete this.pendingRequests[endpoint];
+ })
+ .catch((error) => {
+ delete this.pendingRequests[endpoint];
+ throw error;
+ });
+
+ this.pendingRequests[endpoint] = pendingRequest;
+ }
+
+ return pendingRequest.then(() => this.get(endpoint));
+ }
+}
+
+export default new AjaxCache();