(function () { 'use strict'; angular.module('app.service') .factory('AbstractBridge', ['$http', '$q', '$timeout', 'apiUrl', 'cfg', 'indicator', 'translate', function ($http, $q, $timeout, apiUrl, cfg, indicator, translate) { /** * @name AbstractBridge * @param {Object} options * @constructor */ var AbstractBridge = function (options) { /** * @type {?String} mode 'single'|'multi'|'queue' */ this.mode = 'single'; /** * @type {?Number} timeout */ this.timeout = 30000; /** * @type {String} */ this.controller = undefined; if (options && angular.isObject(options)) { for (var key in options) { if (options.hasOwnProperty(key) && this.hasOwnProperty(key)) { this[key] = options[key]; } } } this.queue = []; }; AbstractBridge.prototype.abort = function (defer) { if (defer._cancelerDefer) { cfg.debug && console.warn('AbstractBridge.abort', this.controller); defer._cancelerDefer.resolve(); this.clearTimeout(defer); } }; AbstractBridge.prototype.setupCanceler = function (defer) { this.clearTimeout(defer); defer._cancelerDefer = $q.defer(); defer._timeoutId = $timeout(this.abort.bind(this, defer), this.timeout); }; AbstractBridge.prototype.clearTimeout = function (defer) { defer._cancelerDefer = null; if (defer._timeoutId) { $timeout.cancel(defer._timeoutId); defer._timeoutId = null; } }; /** * Send request * @param {String} method * @param {String} action * @param {?Object} options * @returns {promise} */ AbstractBridge.prototype.request = function (method, action, options) { // this.cancelerDefer && this.abort(); var deferred = $q.defer(); deferred._indicatorId = 'api.' + this.controller; indicator.start(deferred._indicatorId); this.setupCanceler(deferred); $http(angular.extend({ method: method.toUpperCase(), url: apiUrl + '/' + this.controller + '/' + action, timeout: deferred._cancelerDefer.promise }, options)).then( angular.bind(this, this.onDone, deferred), angular.bind(this, this.onFail, deferred) ); return deferred.promise; }; AbstractBridge.prototype.get = function (action, params, options) { return this.request('GET', action, angular.extend({params: params}, options)); }; AbstractBridge.prototype.post = function (action, data, options) { return this.request('POST', action, angular.extend({data: data}, options)); }; AbstractBridge.prototype.onDone = function (deferred, data) { deferred._indicatorId && indicator.stop(deferred._indicatorId); deferred._timeoutId && this.clearTimeout(deferred); deferred.resolve(data.data); }; AbstractBridge.prototype.onFail = function (deferred, data) { deferred._indicatorId && indicator.stop(deferred._indicatorId); deferred._timeoutId && this.clearTimeout(deferred); if (0 === data.status) { deferred.reject({}); return; } var response = data.data; cfg.debug && console.warn('AbstractBridge: Request Error: ', arguments); if (null == response) { response = {message: translate('Request failed')}; } else if (angular.isString(response)) { response = (response.length < 250) ? {message: response} : {message: translate('Request failed')}; } else { // todo: this is gag if (response.data && response.data.errors) { response.errors = response.data.errors; delete response.data.errors; } } deferred.reject(response); }; return AbstractBridge; }]); })();