3

I'm using the code below in order to simplify the backend requests but I didn't catch how to call either a success method or an error method.

How can I reach the expected behavior commented in the code?

 
app.factory('REST', function ($http, $q, sweetAlert) {

    return {
        load: function (module, action, data) {
            var deferred = $q.defer();
            var promise = deferred.promise;         
            $http
            .post('/api/'+module+'.php?action='+action, data)
            .success(function (data) {

                if(data.error)
                {
                    sweetAlert.swal({
                        title: "Error",
                        text: data.error,
                        type: "warning"
                    });
                //HERE I WANT TO CALL .error(details)
                }
                else
                    deferred.resolve(data.result);

                        }).error(function () {
                //HERE I WANT TO CALL .error(details)
            });

            promise.success = function(fn) {
                promise.then(fn);
                return promise;
            }

            return promise;
        }
    };
});

This is the code which uses the code above:

$scope.login = function () {
    $scope.loading = true;
    var payload = {'credentials': $scope.logindata};
    REST.load('access', 'login', payload).success(function(data) {
        if(data.redirect)
            $state.go(data.redirect);
        $scope.loading = false;
    }).error(function(data) { //THIS SHOULD BE CALLED
        $scope.loading = false;
    });
}
2
  • Regular promises don't have any success()/error() function. They have a then() and a catch() functions. Those are what your client code should call. Read blog.ninja-squad.com/2015/05/28/angularjs-promises Commented Jul 13, 2015 at 7:13
  • Do you mean that you want to call .reject(), not .error()? Commented Jul 14, 2015 at 12:02

2 Answers 2

5

First of all, I strongly discourage you from attaching .success to the promise you are returning. This is not Promises/A-compliant, and its subtle difference from .then (as is implemented by $http) causes a lot of confusion. Just return a pure promise.

Other than that, a few things to note:

1) you don't need another $q.defer and deferred.resolve() - just chain to the original promise of $http and return the resulting promise. (see deferred anti-pattern)

2) to reject a promise - that is, to cause the .catch (not .error - see above about the subtle difference) to fire - you should return $q.reject().

All of the above produces the following:

app.factory('REST', function($http, $q, sweetAlert){
  return {
    load: function(module, action, data) {
      // this "return" returns the promise of $http.then
      return $http.post('/api/' + module + '.php?action=' + action, data)
        .then(function(response) {
          var data = response.data; // .then gets a response, unlike $http.success

          if (data.error) {
            sweetAlert.swal({
              title: "Error",
              text: data.error,
              type: "warning"
            });

            //HERE I WANT TO CALL .error(details)

            return $q.reject(data.error);
          }

          return data.result; // what you would have "resolved"
        });
    }
  };
})

Then, as I said above, use the .then/.catch as you would with promises:

$scope.login = function () {
    $scope.loading = true;
    var payload = {'credentials': $scope.logindata};
    REST.load('access', 'login', payload)
        .then(function(data) {
          if(data.redirect)
             $state.go(data.redirect);
          $scope.loading = false;
        })
        .catch(function(error) {
          $scope.loading = false;
        });
}
Sign up to request clarification or add additional context in comments.

Comments

1

Update yr code as below

app.factory('REST', function ($http, $q, sweetAlert) {
   return {
       load: function (module, action, data) {
              var deferred = $q.defer();                  
                  $http.post('/api/'+module+'.php?action='+action, data)
                          .success(function (data) {
                              if(data.error)
                              {
                                  sweetAlert.swal({
                                      title: "Error",
                                      text: data.error,
                                      type: "warning"
                                  });     
                                 //HERE I WANT TO CALL .error(details)                                
                                 deferred.reject(data.error);
                              }
                              else{
                                deferred.resolve(data.result);
                              }

                         })
                         .error(function (error) {
                              //HERE I WANT TO CALL .error(details)
                              deferred.reject(error);   
                          });

               return defferred.promise;
          }
   };
});

for yr controller

 $scope.login = function () {
     $scope.loading = true;
     var payload = {'credentials': $scope.logindata};
     REST.load('access', 'login', payload).then(
       function(data) {
         if(data.redirect)
             $state.go(data.redirect);
             $scope.loading = false;
       },
       function(error) {
          $scope.loading = false;
       });
   }

Comments

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.