Search code examples
angularjsangular-httpangular-http-interceptors

Intercepting $http responses and passing back new brand new responses


I'm creating an eCommerce store that will have to support multiple payment gateways. One of these payment gateways include the National Australian Bank, which doesn't include an API which communicates with HTTP codes and JSON. Instead, it responds with just text and a status of 200 even if a transaction fails.

In my application I'm using the $http provider to handle these responses, but it will always fire the success function, thus I need to somehow intercept the response before deciding if it's a success or failure.

Here's how it's set up:

// Controller

PaymentService.submit(payment_info).then(function(resp){
  // Do stuff on success
})

// PaymentService#submit

payment.submit = function(data) {
  var strategy;

  // general payment codez

  if (CURRENT_COUNTRY == 'au') {
    strategy = PaymentStrategy.nab.submit(card.number, card.cvv, card.exp_year, card.exp_month);
  }

  return strategy;
}

// PaymentStrategy.nab#submit

service.submit = function(number, cvv, exp_year, exp_month) {

  // payment codez specific to NAB

  return $http.post(resource_path, $httpParamSerializerJQLike(payload), { headers: headers })
}

So the issue is that PaymentService.submit is the promise that was passed back from PaymentStrategy.nab. However that promise will always fire the success callback because the response is always 200 even if the payment failed (that's house National Australian Bank's current system works. It's supposed to be submitted with an HTML form).

I want the PaymentService.submit method to work for any payment gateway - so I need the promise that is passed back to always behave the same. The only place these kinds of unique configurations should occur is within their own strategies.

With all that said, how can I get a response from NAB, normalize that response, and then back another proper response back down the chain?


Solution

  • To convert a successful promise to a rejected promise, throw a value in the success handler. To convert a rejected promise to a successful promise, return a value to the .catch handler.

    return $http.get(url).then(function(response) {
        if (response.data.transactionFailed) {
            //THROW to convert to rejection;
            throw response;
        };
        //OTHERWISE return to chain response
        return response;
    });
    

    The .then method of a promise returns a new promise that resolves to what is returned (or rejected with what is thrown).

    For more information