4

I am doing a http.post request and I am trying to display error message in case anything goes wrong. I am handling the error message in the service, then passing it to the controller and setting it in the $scope. I do not get any JS errors.... any ideas why that would be?

services.js

angular.module('app.services', [])
.factory('Model', function($http) {

    Model.save = function(data) {
        return $http.post(url, data)
            .success(function(data, status, headers) {
                console.log(data);
                console.log(status);
                console.log(headers);
            })
            .error(function(data, status, headers) {
                var requestError = 'Something went wrong! :(';
                return requestError; //pass error message back to $scope
            });
    }

return Model;

});

controllers.js

.controller('Ctrl', function($scope, Model) {   
//form object data
$scope.formInfo = {};

//form save 
$scope.saveData = function() {
    //console.log($scope.formInfo);

    $scope.requestError = '';

    //form data
    var data = {name: $scope.formInfo.name, description: $scope.formInfo.description, token: "/api/v1/tokens/1/"};

    Model.save(data).then(function(requestError) {
        alert(requestError);
        if (requestError === '') {
            //do nothing for now
        }
        else {
            $scope.requestError = requestError;
        }
    });

};

})

4
  • doesn't seem to work is not an error description, e.g. do you get any JS error? Commented Aug 3, 2014 at 15:05
  • 1
    returning from error or success does nothing, fyi. Commented Aug 3, 2014 at 15:07
  • No, I do not get any JS error. If I do console.log in the service I do get my message :) Commented Aug 3, 2014 at 15:07
  • 2
    Additionally, the first callback to .then is the success callback. If the request resulted in error, you'll need to use the second one, or, use the .catch method. Commented Aug 3, 2014 at 15:08

1 Answer 1

8

A promise has two end states: resolved (success) or rejected (error).

In the controller, the then() function needs two different handlers if you want to access both states. The first handler only receives resolved (success) promises from the service. To also handle rejected (error) promises from the service, you'll need something like this:

Model.save(data).then(function(success) { ... }, function(error) { ... });

If you only care about the errors for some reason, use either of these (which are equivalent):

Model.save(data).then(null, function(error) { ... });
Model.save(data).catch(function(error) { ... });

In your service, make sure you're actually returned a rejected (error) promise back to the controller in the event of an error. You do this by using return $q.reject(requestError) instead of just return requestError.


Important note: Since you're using $http, this will already reject promises in the case of an HTTP error. If you don't handle rejected (error) promises in the service, they'll automatically be passed through to the controller's error handler. You may want to simply let $http's rejection pass through, and not have an error handler in the service. You can do this by simply removing .error() in the service. This allows the HTTP error to be handled by the controller directly. (This may or may not be desirable, depending on what kind of error handling you want to do).

The basic pattern I tend to follow with my HTTP services looks like this, which returns either a resolved promise with just the downloaded data, or returns the rejected promise (error) that comes out of $http directly to the controller:

return $http.get(config).then(function(success) { return success.data });
Sign up to request clarification or add additional context in comments.

4 Comments

Ah! Ok, so I don't need to pass the error message from the service, I can set it to $scope in the controller :)
No, quite the opposite, you should pass it from the service! If there's no specific message you can give, it's fine to put the message text itself in the controller, but you should determine success/failure by either resolving or rejecting the promise from the service itself.
Thanks for the detailed response, it clears a lot of uncertainty
@user113215, Can you share the code in the controller so I can understand how it hooks up end to end? Would it be: var data = Service.GetConfig(config).then(null, function(error){alert(error);});

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.