From c464b05b1740f84d61f0210af713e991e7d16124 Mon Sep 17 00:00:00 2001 From: Gustavo Martin Morcuende Date: Fri, 28 Aug 2015 20:09:25 +0200 Subject: [PATCH] showcase: messing around with AngularJS $q (Promise) --- .../src/showcase/app/rest/rest.controller.js | 19 +++-- .../showcase/src/showcase/app/rest/rest.service.js | 85 +++++++++++++++++----- 2 files changed, 79 insertions(+), 25 deletions(-) diff --git a/angularjs/showcase/src/showcase/app/rest/rest.controller.js b/angularjs/showcase/src/showcase/app/rest/rest.controller.js index a03d8cb..0c08dda 100644 --- a/angularjs/showcase/src/showcase/app/rest/rest.controller.js +++ b/angularjs/showcase/src/showcase/app/rest/rest.controller.js @@ -21,7 +21,7 @@ * Rest controller. */ /* @ngInject */ - function Rest($location, cars) { + function Rest($log, cars) { var vm = this; vm.example = { text: 'try to send data', @@ -29,14 +29,19 @@ singleModel: 1 }; vm.getCars = getCars; - vm.cars = undefined; function getCars() { - cars.getAll().then(function (data) { - // Because cars service swallows errors my success function will always be called even when error. - // Alternative: using $q.reject when errors in cars service? - vm.cars = data; - }); + // ES6 way. success and error are deprecated because they are not following the ES6 way. + cars.getAll().then( + // Success + function (value) { + vm.cars = value; + }, + // Error + function(reason) { + $log.debug('Rest controller error: ' + reason); + } + ); } } diff --git a/angularjs/showcase/src/showcase/app/rest/rest.service.js b/angularjs/showcase/src/showcase/app/rest/rest.service.js index 396474f..08c095b 100644 --- a/angularjs/showcase/src/showcase/app/rest/rest.service.js +++ b/angularjs/showcase/src/showcase/app/rest/rest.service.js @@ -22,7 +22,7 @@ * Rest service. */ /* @ngInject */ - function cars($http, $log, API) { + function cars($http, $log, $q, API) { return { getAll: getAll }; @@ -37,19 +37,15 @@ */ function getAll() { return $http.get(API.CARS) - // a) Using success and error from promise. They are deprecated. DO NOT USE THEM!!! + // a) Using success and error from promise. They are deprecated because it is not the ES6 way. DO NOT USE THEM! // https://github.com/angular/angular.js/commit/a8f7e9cfde82ed7eaba3a868d8acafdf57f2d76f // .success(successAlternative) // .error(errorAlternative) - // b) Using then from promise + // b) Using then from promise. ES6 way. .then(success, error, notify) - // catch will be called when there is no error function. In this case it will never be called - // because we already have the error function. - .catch(failed); - // BE CAREFUL!!! If you use error function or catch, when there are errors the success method in the upper layer - // (my Rest controller) will be ALWAYS called. It is as if because we caught errors in this layer they won't be - // seen by the upper layers using this service :( - // Alternative: return $q.reject from errors in this layer? + // Pattern: either use error callback or catch but not the same as the same time!!!! + // .catch(failed) + .finally(finalizer); function success(resp) { /** @@ -75,10 +71,25 @@ * status: 200 * statusText: "OK" */ - return resp.data; + + // In this way, then next chained promise will use just its success callback. :( + // What means, promise will be resolved immediately!!! If it is what you want go ahead. + //return resp.data; + + // Better return promise. :) Two options: + + // a) ES6 way (it doesn't have notify :( + // return $q(function(resolve) { + // resolve(resp.data); + // }) + + // b) The CommonJS Promise way. It has the notify method (which I am not using here) + var deferred = $q.defer(); + deferred.resolve(resp.data); + return deferred.promise; } - // DO NOT USE IT!!! This way has been deprecated. + // DO NOT USE IT!!! This way has been deprecated because it is not the ES6 way. function successAlternative(data, status, headers, config) { $log.debug('XHR SuccessAlternative for getAll. SuccessAlternative, data: ' + data); $log.debug('XHR SuccessAlternative for getAll. SuccessAlternative, status: ' + status); @@ -86,7 +97,7 @@ $log.debug('XHR SuccessAlternative for getAll. SuccessAlternative, config: ' + config); } - function error(resp) { + function error(reason) { /** * resp, object containing: * @@ -103,13 +114,29 @@ * status: 500 * statusText: "Internal Server Error" */ - $log.debug('XHR Error for getAll. Error: ' + resp.data); + $log.debug('XHR Error for getAll. Error: ' + reason.data); + + // In this way, then next chained promise will use just its success callback. :( + // What means, promise will be resolved immediately!!! If it is what you want go ahead. + //return resp.data; + + // Better return promise. :) Three options: + + // a) ES6 way, it doesn't have notify :( + // return $q(function(resolve, reject) { + // reject(reason.data); + // }) + + // b) The CommonJS Promise way. It has the notify method (which I am not using here) + // var deferred = $q.defer(); + // deferred.reject(reason.data); + // return deferred.promise; - // Should I return $q.reject instead? Right now, the success method in upper layers will always be called. :( - return resp.data; + // c) The CommonJS Promise way. The same as b) but with less code :) + return $q.reject(reason.data); } - // DO NOT USE IT!!! This way has been deprecated. + // DO NOT USE IT!!! This way has been deprecated because it is not the ES6 way. function errorAlternative(data, status, headers, config) { $log.debug('XHR ErrorAlternative for getAll. ErrorAlternative, data: ' + data); $log.debug('XHR ErrorAlternative for getAll. ErrorAlternative, status: ' + status); @@ -140,7 +167,29 @@ */ $log.debug('XHR Failed for getAll. Reason: ' + reason); - return reason.data; + // In this way, then next chained promise will use just its success callback. + // What means, promise will be resolved immediately!!! If it is what you want go ahead. + //return resp.data; + + // Better return promise. :) Three options: + + // a) ES6 way, it doesn't have notify :( + // return $q(function(resolve, reject) { + // reject(reason.data); + // }) + + // b) The CommonJS Promise way. It has the notify method (which I am not using here) + // var deferred = $q.defer(); + // deferred.reject(reason.data); + // return deferred.promise; + + // c) The CommonJS Promise way. The same as b) but with less code :) + return $q.reject(reason.data); + + } + + function finalizer() { + } } } -- 2.1.4