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

How to correctly override `errResponse` which is passed to the `catch(function(errResponse){` function?

这是我的控制器:

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/工厂:

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() 函数。

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

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

  1. 处理成功响应
  2. 处理错误

您不需要 catch 块。只需添加回调函数以防错误覆盖响应,如下所示:

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";
                 });                    
            }
         };

看来您对 promises 的理解还不够深入 :) 我建议您多了解一下。

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

所以像这样:

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
      });
  }
};

When I try to run this code and call self.add() on my controller, I get an error saying TypeError: Cannot read property 'catch' of 'undefined' pointing to the line .catch(function(errorResponse) { in my controller. I'm guessing this is because there is no then() function.

这是一个错误的猜测。 self.add() returned undefined 因为函数省略了 return 语句。当函数省略 return 语句时,它们 return 原始值 undefined。原语 undefined 上既没有 .then 方法也没有 .catch 方法。因此 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 语句,则它 return 是 undefined 的原始值。这意味着拒绝将转换为 成功 承诺,解析为值 undefined。随后它将跳过控制器中的.catch方法。

有关详细信息,请参阅