diff --git a/app/assets/javascripts/lib/utils/poll.js b/app/assets/javascripts/lib/utils/poll.js new file mode 100644 index 0000000000000000000000000000000000000000..b6c7c809525a196ebddb5c76f057f0b88739047b --- /dev/null +++ b/app/assets/javascripts/lib/utils/poll.js @@ -0,0 +1,54 @@ +import Vue from 'vue'; +import VueResource from 'vue-resource'; +import httpStatusCodes from './http_status'; + +Vue.use(VueResource); + +/** + * Polling utility for handling realtime updates with Vue.Resource get method. + * + * @example + * new poll({ + * url: 'endopoint', + * data: {}, + * successCallback: () => {} + * errorCallback: () => {} + * }).makeRequest(); + * + * + * 1. Checks for response and headers before start polling + * 2. Interval is provided by `X-Poll-Interval` header. + * 3. If `X-Poll-Interval` is -1, we stop polling + * 4. If HTTP response is 200, we poll. + * 5. If HTTP response is different from 200, we stop polling. + * + */ +export default class poll { + constructor(options) { + this.options = options || {}; + + this.intervalHeader = 'POLL-INTERVAL'; + } + + checkConditions(response) { + const headers = gl.utils.normalizeHeaders(response.headers); + const pollInterval = headers[this.intervalHeader]; + + if (pollInterval > 0 && response.status === httpStatusCodes.OK) { + this.options.successCallback(response); + setTimeout(() => { + this.makeRequest() + .then(this.checkConditions) + .catch(error => this.options.errorCallback(error)); + }, pollInterval); + } else { + this.options.successCallback(response); + } + } + + makeRequest() { + return Vue.http.get(this.options.url, this.options.data) + .then(this.checkConditions) + .catch(error => this.options.errorCallback(error)); + } +}