Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular.js Passing error message from service to controller $scope

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

};

})

like image 829
Claudiu S Avatar asked Feb 13 '23 08:02

Claudiu S


1 Answers

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 });
like image 60
quietmint Avatar answered Feb 15 '23 04:02

quietmint