这是我的控制者:
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()
函数,因为不需要做任何事情如果成功的话)?
答案 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()块接受两个函数:
您不需要捕获块。只需添加回调函数以防错误覆盖响应,如下所示:
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";
});
}
};