简体   繁体   中英

Angular apply same success and error function bodies to different $http requests

I am not sure what exact keywords to search for this. So I decided to ask here for help.

I think this is more a JavaScript related question rather than angular. Anyways here is my problem.

I am in a DRY situation (don't repeat yourself). I am trying to merge the two of my $http.put and $http.delete methods' success and error function under single one, because they share the same functionalities.

Here is my current code

// Delete permanenty button action
  $scope.delete_donor = function(form) {
    $http.delete(url)
      .success(function() {
        // @TODO DRY? DELETE UPDATE delete_donor update_donor
        response.ipv4 = INT_TO_STR_IP(response.ipv4)
        // Show deleted data to user after operation
        $scope.donor.saved_data = response.saved_data
        $location.path("/")
      })
      .error(function(response) {
        $scope.donor.validation_errors = SERVER_VALIDATION_ERROR(response)
      })
  }
  // Save changes button action
  $scope.update_donor = function(form) {
    var body = $scope.donor.data
    delete body.ipv4
    $http.put(url, body)
      .success(function(response) {
        // @TODO DRY? DELETE UPDATE delete_donor update_donor
        response.ipv4 = INT_TO_STR_IP(response.ipv4)
        // Show new updated data to user after operation
        $scope.donor.saved_data = response.saved_data
        $location.path("/")
      })
      .error(function(response) {
        $scope.donor.validation_errors = SERVER_VALIDATION_ERROR(response)
      })

As you can see $http.delete().success().error() and $http.put().success().error() methods are same.

I am trying to do something like

WHATSTHIS unify(response) {
  WOOT .success(function(response) { // SAME CODE BODY })
  WOOT .error(function(response) { // SAME CODE BODY })
}

// Delete permanenty button action
  $scope.delete_donor = function(form) {
    $http.delete(url)
      .unify(response)
  }
  // Save changes button action
  $scope.update_donor = function(form) {
    var body = $scope.donor.data
    delete body.ipv4
    $http.put(url, body)
      .unify(response)

I just know one way to achieve something similiar which is:

var unifySuccess = function(response) {
  // DO
}
var unifySuccess = function(response) {
  // DO
}

// Delete permanenty button action
  $scope.delete_donor = function(form) {
    $http.delete(url)
      .sucesss(unifySuccess)
      .error(unifyError)

But maybe there is an other clever way to do this?

Thanks for your help.

what you could do is create your own http request service that will do these functionalities and return the promise as a response

something like this

angular.module('myApp')
  .service('proxyHttp', function($http) {
    return function(options) {
      return $http(options)
        .then(
          function() {
            // success callback
          },
          function() {
            // error callback
          });
    }
  })

Update: For example

 angular.module('myApp', []) .service('proxyHttp', function($http, $q) { return function(options) { console.log('Run proxy http'); return $http(options) .then( function(response, status) { console.log('always do this on success'); // success callback return response; // here we return the response or what ever you want, // and we can continue handling it }) .catch(function() { console.log('we failed!'); // error callback return $q.reject(); }) } }) .controller('testController', function($scope, proxyHttp) { $scope.testError = function() { console.log('Run test error method'); proxyHttp({ url: 'http://www.google.com', method: 'GET' }) .then( function() {}) .catch(function() { console.log('we continue handling our error here...'); }); } $scope.testSuccess = function() { console.log('Run test success method'); proxyHttp({ url: 'http://httpbin.org/ip', method: 'GET' }) .then( function(response) { console.log('continue chaining after success for the original promise'); console.log('Response data: ' response.data.origin); console.log('read more about pomise and chaining here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise'); }) .catch(function() { console.log('error'); }); } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="myApp"> <div ng-controller="testController"> <button ng-click="testError()">Click Me for error!</button> <br/> <br/> <button ng-click="testSuccess()">Click Me for success!</button> </div> </div> 

Depending on your actual use case, this may end up sacrificing too much readability to be helpful, but since you asked specifically for cleverness:

function attachHttpResponseHandling(httpPromise) {
    httpPromise
        .success(function(response) {
            response.ipv4 = INT_TO_STR_IP(response.ipv4);
            // Show new updated data to user after operation
            $scope.donor.saved_data = response.saved_data;
            $location.path("/");
        })
        .error(function(response) {
            $scope.donor.validation_errors = SERVER_VALIDATION_ERROR(response);
        })
    ;
}
// Delete permanenty button action
$scope.delete_donor = function(form) {
    attachHttpResponseHandling($http.delete(url));
};
// Save changes button action
$scope.update_donor = function(form) {
    var body = $scope.donor.data;
    delete body.ipv4;
    attachHttpResponseHandling($http.put(url, body));
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM