问题
I've been at this for hours and I can't figure out why angular is not triggering my error call back when my rails back-end raises a proper error. I'm using angular 1.2.0rc1.
According to the documentation:
non-GET "class" actions: Resource.action([parameters], postData, [success], [error])
And I'm using it in my angular controller during a save product operation:
$scope.saveProduct = function(product){
if (product.id) {
Product.update({id: product.id},{product: product}, function(data){
console.log('handle success')
}, function(){
console.log('handle error') //THIS IS NEVER OUTPUT!
});
}
}
Here is the resource definition:
angular.module('sellbriteApp.resources').factory('Product', function ($resource) {
return $resource('/api/products/:id', { id: "@id" },
{
'create': { method: 'POST' },
'index': { method: 'GET', isArray: true },
'show': { method: 'GET', isArray: false },
'update': { method: 'PUT' },
'destroy': { method: 'DELETE' }
}
);
});
Here is my rails controller:
def update
respond_to do |format|
if @product.update(product_params)
format.html { redirect_to [:edit, @product], notice: 'Product was successfully updated.' }
format.json { render 'products/show.json.jbuilder', status: :accepted }
else
format.html { render action: 'edit' }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
Rails returns a 422 status when attempting to save a product with a duplicate sku, and I want to display an error msg on the front end.
I would expect that angular should execute the error handling function provided in the update call, but I can't get that far. Instead in my console I see:
TypeError: Cannot read property 'data' of undefined
with an unhelpful stacktrace:
TypeError: Cannot read property 'data' of undefined
at $http.then.value.$resolved (http://localhost:9000/bower_components/angular-resource/angular-resource.js:477:32)
at wrappedCallback (http://localhost:9000/bower_components/angular/angular.js:9042:59)
at wrappedCallback (http://localhost:9000/bower_components/angular/angular.js:9042:59)
at http://localhost:9000/bower_components/angular/angular.js:9128:26
at Object.Scope.$eval (http://localhost:9000/bower_components/angular/angular.js:9953:28)
at Object.Scope.$digest (http://localhost:9000/bower_components/angular/angular.js:9809:23)
at Object.$delegate.__proto__.$digest (<anonymous>:844:31)
at Object.Scope.$apply (http://localhost:9000/bower_components/angular/angular.js:10039:24)
at Object.$delegate.__proto__.$apply (<anonymous>:855:30)
at done (http://localhost:9000/bower_components/angular/angular.js:6542:45)
What am I missing?
UPDATE:
Apparently this http interceptor is related. If I comment this code out, the error function is called. I had copied this snippet from some where else and modified it in order to redirect a user to the sign_up page if they hit a rails api when they are not logged in. It must be interfering, but I'm not sure how I should fix it.
App.config(['$httpProvider', function ($httpProvider) {
$httpProvider.responseInterceptors.push('securityInterceptor');
}]);
App.factory('securityInterceptor', ['$injector', '$location', '$cookieStore', function ($injector,$location,$cookieStore) {
return function(promise) {
var $http = $injector.get('$http');
return promise.then(null, function(response){
if (response.status === 401) {
$cookieStore.remove('_angular_devise_merchant');
toastr.warning('You are logged out');
$location.path('/sign_in');
}
});
};
}]);
回答1:
You need to reject the promise in your interceptor as well, otherwise its considered as if you've 'handled' the exception.
So:
App.factory('securityInterceptor', ['$injector', '$location', '$cookieStore', '$q', function ($injector,$location,$cookieStore, $q) {
return function(promise) {
var $http = $injector.get('$http');
return promise.then(null, function(response){
if (response.status === 401) {
$cookieStore.remove('_angular_devise_merchant');
toastr.warning('You are logged out');
$location.path('/sign_in');
}
return $q.reject(response);
});
};
}]);
来源:https://stackoverflow.com/questions/18907117/angular-resource-not-invoking-my-error-callback-function