/** * @name RestangularService * Base class to be extended by classes which will provide access * to te Noosfero REST API * * @export RestangularService * @abstract * @class RestangularService * @template T */ export abstract class RestangularService { /** * Creates an instance of RestangularService. * * @param {restangular.IService} Restangular (description) * @param {ng.IQService} $q (description) * @param {ng.ILogService} $log (description) */ constructor(protected restangularService: restangular.IService, protected $q: ng.IQService, protected $log: ng.ILogService) { // TODO this.restangularService.setResponseInterceptor((data, operation, what, url, response, deferred) => { let transformedData: any = data; if (operation === "getList" && url.endsWith("/" + this.getDataKeys().plural)) { transformedData = data[this.getDataKeys()["plural"]]; return transformedData; } else { return data; } }); } protected extractData(response: restangular.IResponse): noosfero.RestResult { let dataKey: string; if (response.data && this.getDataKeys()) { if ((response.data).hasOwnProperty(this.getDataKeys().singular)) { dataKey = this.getDataKeys().singular; } else if ((response.data).hasOwnProperty(this.getDataKeys().plural)) { dataKey = this.getDataKeys().plural; } } return { data: response.data[dataKey], headers: response.headers }; }; protected buildResult(response: restangular.IResponse): noosfero.RestResult { return { data: response.data, headers: response.headers }; }; /** * Abstract getPath() method is used to mount the url * on REST Operations * @protected * @abstract * @returns {string} The path of the REST endpoint */ public abstract getResourcePath(): string; /** * Abstract getDataKeys() * * Should be implemented into the child classes and * returns the singular and plural names of the represented resource * * @protected * @abstract * @returns {{ singular: string, plural: string }} (description) */ protected abstract getDataKeys(): { singular: string, plural: string }; /** * Do a HTTP GET call to the resource represented using the id provided * * @protected * @param {number} id The resource id * @returns {ng.IPromise} Returns a Promise to the Generic Type */ public get(id: number, rootElement?: restangular.IElement, queryParams?: any, headers?: any): ng.IPromise> { let deferred = this.$q.defer>(); let restRequest: ng.IPromise>; if (rootElement) { restRequest = rootElement.one(this.getResourcePath(), id).get(queryParams, headers); } else { restRequest = this.restangularService.one(this.getResourcePath(), id).get(queryParams, headers); } restRequest.then(this.getHandleSuccessFunction(deferred)) .catch(this.getHandleErrorFunction(deferred)); return deferred.promise; } /** * Do a HTTP GET call to the resource collection represented * * @protected * @param {number} id (description) * @returns {ng.IPromise} Returns a Promise to the Generic Type */ public list(rootElement?: restangular.IElement, queryParams?: any, headers?: any): ng.IPromise> { let deferred = this.$q.defer>(); let restRequest: ng.IPromise; debugger; if (rootElement) { restRequest = rootElement.customGET(this.getResourcePath(), queryParams, headers); } else { restRequest = this.restangularService.all(this.getResourcePath()).customGET("", queryParams, headers); } restRequest .then(this.getHandleSuccessFunction(deferred)) .catch(this.getHandleErrorFunction(deferred)); return deferred.promise; } public listSubElements(obj: T, subElement: string, queryParams?: any, headers?: any): ng.IPromise> { let deferred = this.$q.defer>(); let restRequest: ng.IPromise>; restRequest = obj.all(subElement).get(queryParams, headers); restRequest.then(this.getHandleSuccessFunction(deferred)) .catch(this.getHandleErrorFunction(deferred)); return deferred.promise;; } /** * Removes the object provided from the resource collection, * calls DELETE /resourcepath/:resourceId */ public remove(obj: T, queryParams?: any, headers?: any): ng.IPromise> { let deferred = this.$q.defer>(); let restRequest: ng.IPromise>; restRequest = obj.remove(queryParams, headers); restRequest .then(this.getHandleSuccessFunction(deferred)) .catch(this.getHandleErrorFunction(deferred)); return deferred.promise; } /** * Updates the object into the resource collection * calls PUT /resourcePath/:resourceId {object} */ public update(obj: T, queryParams?: any, headers?: any): ng.IPromise> { let deferred = this.$q.defer>(); let restRequest: ng.IPromise>; restRequest = obj.put(queryParams, headers); restRequest.then(this.getHandleSuccessFunction(deferred)) .catch(this.getHandleErrorFunction(deferred)); return deferred.promise; } /** * Creates a new Resource into the resource collection * calls POST /resourcePath */ public create(obj: T, rootElement?: noosfero.RestModel, queryParams?: any, headers?: any): ng.IPromise> { let deferred = this.$q.defer>(); let restRequest: ng.IPromise>; if (rootElement) { restRequest = rootElement.all(this.getResourcePath()).post(obj, queryParams, headers); } else { restRequest = this.restangularService.all(this.getResourcePath()).post(obj, queryParams, headers); } restRequest.then(this.getHandleSuccessFunction(deferred)) .catch(this.getHandleErrorFunction(deferred)); return deferred.promise; } /** * Returns a Restangular IElement representing the */ protected getElement(id: number, rootElement?: noosfero.RestModel): restangular.IElement { if (rootElement) { return rootElement.one(this.getResourcePath(), id); } else { return this.restangularService.one(this.getResourcePath(), id); } } // /** // * (description) // * // * @protected // * @template T // * @param {restangular.IElement} elementRoot (description) // * @param {*} [element] (description) // * @param {string} [path] (description) // * @param {*} [params] (description) // * @param {*} [headers] (description) // * @returns {ng.IPromise} (description) // */ // protected post(elementRoot: restangular.IElement, element?: any, path?: string, params?: any, headers?: any): ng.IPromise { // let deferred = this.$q.defer(); // let postData = {}; // postData[this.getDataKeys().singular] = element; // this.customPOST( // elementRoot, // postData, // this.getResourcePath(), // {} // ) // .then(this.getPostSuccessHandleFunction(deferred)) // .catch(this.getHandleErrorFunction(deferred)); // return deferred.promise; // } // protected customGET(elementRoot: restangular.IElement, path?: string, params?: any, headers?: any): ng.IPromise { // let deferred = this.$q.defer(); // if (headers) { // headers['Content-Type'] = 'application/json'; // } else { // headers = { 'Content-Type': 'application/json' }; // } // elementRoot.customGET(path, params, headers) // .then(this.getHandleSuccessFunction(deferred)) // .catch(this.getHandleErrorFunction(deferred)); // return deferred.promise; // } // /** // * (description) // * // * @protected // * @param {restangular.IElement} elementRoot (description) // * @param {*} [elem] (description) // * @param {string} [path] (description) // * @param {*} [params] (description) // * @param {*} [headers] (description) // * @returns (description) // */ // protected customPOST(elementRoot: restangular.IElement, elem?: any, path?: string, params?: any, headers?: any) { // if (headers) { // headers['Content-Type'] = 'application/json'; // } else { // headers = { 'Content-Type': 'application/json' }; // } // return elementRoot.customPOST(elem, path, params, headers); // } /** HANDLERS */ protected getHandleSuccessFunction(deferred: ng.IDeferred>, responseKey?: string): (response: restangular.IResponse) => void { let self = this; /** * (description) * * @param {restangular.IResponse} response (description) */ let successFunction = (response: restangular.IResponse): void => { if (self.$log) { self.$log.debug("Request successfull executed", response.data, self, response); } deferred.resolve(this.extractData(response)); //deferred.resolve(this.buildResult(response)); }; return successFunction; } /** * (description) * * @template T * @param {ng.IDeferred} deferred (description) * @returns {(response: restangular.IResponse) => void} (description) */ getHandleErrorFunction(deferred: ng.IDeferred): (response: restangular.IResponse) => void { let self = this; /** * (description) * * @param {restangular.IResponse} response (description) */ let successFunction = (response: restangular.IResponse): void => { if (self.$log) { self.$log.error("Error executing request", self, response); } deferred.reject(response); }; return successFunction; } /** END HANDLERS */ // /** // * (description) // * // * @template T // * @param {ng.IDeferred} deferred (description) // * @returns {(response: restangular.IResponse) => void} (description) // */ // protected getPostSuccessHandleFunction(deferred: ng.IDeferred): (response: restangular.IResponse) => void { // let self = this; // /** // * (description) // * // * @param {restangular.IResponse} response (description) // */ // let successFunction = (response: restangular.IResponse): void => { // if (self.$log) { // self.$log.debug("Post successfully executed", self, response); // } // let data = response.data; // // if ((data).hasOwnProperty(self.getDataKeys().singular)) { // deferred.resolve(data[self.getDataKeys().singular]); // } else { // deferred.resolve(data); // } // }; // return successFunction; // } }