如何正确覆盖传递给`catch(函数(errResponse){`函数的`errResponse`?

时间:2017-03-31 00:19:29

标签: angularjs angular-promise angular-services angular-http

这是我的控制者:

angular.module("AuthenticationApp", ["BaseApp"])
    .controller("MainCtrl", ["$http", "$window", "BaseService", function($http, $window, BaseService) {
        var self = this;

        self.add = function() {
            BaseService.add.user(self.user)
                .catch(function(errorResponse) {
                    self.cerrorMessages = errorResponse.data;
                });
        };

这是我的BaseApp / factory:

angular.module("BaseApp", [])
    .config(['$httpProvider', function($httpProvider) {
        $httpProvider.defaults.xsrfCookieName = 'csrftoken';
        $httpProvider.defaults.xsrfHeaderName = 'X-CSRFToken';
    }])

    .factory("BaseService", ["$http", "$window", function($http, $window) {
        var self = this;

        self.add = {
            user: function(user) {
                $http.post("/users/", user)
                .then(function(response) {
                    $http.post("/api-auth/login", user)
                    .then(function(response) {
                        $window.location.href = "/";
                    });
                // if there are errors, rewrite the error messages
                }).catch(function(response) {
                     for (prop in response.data) {
                         if (prop == "email") {
                             response.data[prop] = "Please enter a valid email address.";
                         } else if (prop == "username") {
                             response.data[prop] = "Please enter a valid username";
                         }
                     }
                });
            }
         };

当我尝试运行此代码并在我的控制器上调用self.add()时,出现错误,指出TypeError: Cannot read property 'catch' of undefined指向控制器中的行.catch(function(errorResponse) {。我猜这是因为没有then()功能。

我应该怎么做才能正确覆盖传递给控制器​​errResponse函数的.catch()参数(没有.then()函数,因为不需要做任何事情如果成功的话)?

3 个答案:

答案 0 :(得分:1)

您似乎对承诺没有充分理解:)我建议您更多地了解它们。

当你致电BaseService.add.user时,这应该会返回一个承诺。如果这是承诺,您只能使用.catch。另请注意,在链接承诺时,您需要返回一个承诺!

这样的事情:

self.add = {
  user: function(user) {
    return $http.post("/users/", user)
      .then(function(response) {
        return $http.post("/api-auth/login", user)
      })
      .then(function(response) {
        $window.location.href = "/";
      })
      .catch(function(response) {
        // error stuff
      });
  }
};

答案 1 :(得分:1)

  

当我尝试运行此代码并在我的控制器上调用self.add()时,出现错误,指出TypeError: Cannot read property 'catch' of 'undefined'指向控制器中的行.catch(function(errorResponse) {。我猜这是因为没有then()函数。

这是一个错误的猜测。 self.add()返回undefined,因为该函数省略了return语句。当函数省略return语句时,它们返回原始值undefined。原始.then上既没有.catch方法也没有undefined方法。因此TypeError: Cannot read property 'catch'

return httpPromise:

非常重要
user: function(user) {
    //vvvv RETURN the promise
    return $http.post("/users/", user)
      .then(function successHandler(response) {
        //vvvv RETURN to chain
        return $http.post("/api-auth/login", user)
    }).then(function successHandler(response) {
        $window.location.href = "/";
    // if there are errors, rewrite the error messages
    }).catch(function rejectHandler(errorResponse) {
         for (prop in errorResponse.data) {
             if (prop == "email") {
                 errorResponse.data[prop] = "Please enter a valid email address.";
             } else if (prop == "username") {
                 errorResponse.data[prop] = "Please enter a valid username";
             }
         }
         //vvvv THROW to chain rejections
         throw errorResponse;
    });
}

同样在拒绝处理程序中使用throw statement非常重要。否则,拒绝将转换成功。如果拒绝处理程序省略了throw语句,则返回原始值undefined。这意味着拒绝将转换为成功的承诺,该承诺将解析为undefined的值。随后它将跳过控制器中的.catch方法。

有关详细信息,请参阅Angular execution order with $q

答案 2 :(得分:0)

.then()块接受两个函数:

  1. 处理成功的回复
  2. 处理错误
  3. 您不需要捕获块。只需添加回调函数以防错误覆盖响应,如下所示:

    self.add = {
                user: function(user) {
                    $http.post("/users/", user)
                    .then(function(response) {
                        $http.post("/api-auth/login", user)
                        .then(function(response) {
                            $window.location.href = "/";
                        }, function errorCallback(response) {
                            for (prop in response.data) {
                             if (prop == "email") {
                                 response.data[prop] = "Please enter a valid email address.";
                             } else if (prop == "username") {
                                 response.data[prop] = "Please enter a valid username";
                     });                    
                }
             };