Search code examples
javascriptangularjspromiseangular-promise

(Angular)Js - how to simplify promise result?


I come from an embedded C background, and am self-taught in AngularJs 1.x; I suspect that my question is a generic JS question, rather than AngularJs specific.

I find this sort of pattern repeating in my code:

                $http.get(url)
                    .success(function(data, status, headers, config)
                    {
                       console.log('Success');
                    });

               })
                .error(function(data, status, headers, config)
                {
                    console.error('Error !');
                });

Being a C guy, I am not similar with lambdas, although I am comfortable with callbacks.

The code for the success and failure parts can be very large, and it makes the code seem messy - especially seeing all that code passed as a parameter.

I am guessing that the parameters to $http is/are (a) promise(s).

Is there some way that I can make the code more modular, and easier to read & maintain?

For instance, I imagine that I could declare some success/failure functions & invoke those, stemming like:

function it_succded(data, status, headers, config))
{
    console.log('Success');
});

function it_failed(data, status, headers, config)
{
    console.error('Error !');
});

$http.get(url)
.success(function(data, status, headers, config)
 {
     it_succded(data, status, headers, config))
   });
})
.error(function(data, status, headers, config)
 {
    it_failed(data, status, headers, config)
  });
});

Of course, I could just code it & see, but ask here because I want to learn, and hope for an explanation from someone who truly understands this, preferably someone who codes (Angular)Js professionally.


Solution

  • For using the promise interface, you should not use .success() or .error(): they are deprecated. Instead, use .then() and catch(). The parameters these callbacks receive are slightly different:

    $http.get(url).then(function(response) {
         console.log("Success", response.data);
    }).catch(function(response) {
         console.log("Error", response.status);
    });
    

    response is an object that has the expected properties:

    • data{string|Object} – The response body transformed with the transform functions.
    • status{number} – HTTP status code of the response.
    • headers{function([headerName])} – Header getter function.
    • config{Object} – The configuration object that was used to generate the request.
    • statusText{string} – HTTP status text of the response.
    • xhrStatus{string} – Status of the XMLHttpRequest (complete, error, timeout or abort).

    You could indeed define the callback functions separately, and then your callback arguments can just be function references:

    function it_succded(response) {
         console.log("Success", response.data);
    }
    function it_failed(response) {
         console.log("HTTP Error", response.status, response.statusText);
    }
    $http.get(url).then(it_succded).catch(it_failed);
    

    You could define these functions as methods, e.g. on the $scope object:

    $scope.it_succded = function (response) {
         console.log("Success", response.data);
         $scope.data = response.data;
    }
    $scope.it_failed = function (response) {
         console.log("HTTP Error", response.status, response.statusText);
    }
    $http.get(url).then($scope.it_succded).catch($scope.it_failed);
    

    Little note: Be aware that this will not be set when these callbacks are called by the Promise implementation. So either do not use this in them, or define them as arrow functions (this will then be whatever it is in the lexical context), bind the functions to a specific this object, or provide little wrapper callbacks:

    .then(function(response) { 
         return $scope.it_succded(response);
    })