showcase: messing around with AngularJS $q (Promise)
authorGustavo Martin Morcuende <gu.martinm@gmail.com>
Fri, 28 Aug 2015 18:09:25 +0000 (20:09 +0200)
committerGustavo Martin Morcuende <gu.martinm@gmail.com>
Fri, 28 Aug 2015 18:09:25 +0000 (20:09 +0200)
angularjs/showcase/src/showcase/app/rest/rest.controller.js
angularjs/showcase/src/showcase/app/rest/rest.service.js

index a03d8cb..0c08dda 100644 (file)
@@ -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',
       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);
+        }
+      );
     }
   }
 
index 396474f..08c095b 100644 (file)
@@ -22,7 +22,7 @@
    * Rest service.
    */
   /* @ngInject */
-  function cars($http, $log, API) {
+  function cars($http, $log, $q, API) {
     return {
       getAll: getAll
     };
      */
     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) {
         /**
          * 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:
          *
          * 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);
          */
         $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() {
+
       }
     }
   }