Tuesday, August 12, 2014

AngularJS http interceptor for DTO

In my single page applications I standardized data exchange between client side javascript framework (AngularJS) and a rest service (WebAPI) using a DTO. I am using the following DTO to properly encapsulate data from server to client. Please refer to my SPA DTO blog for more details.

public class AjaxModel<T>
{
    public bool Success { get; set; }
    public string Message { get; set; }
    public T Model { get; set; }
}

As you see, I defined a generic class which shuttles the data using generic object. In addition it also carries a boolean variable specifying whether the call is success or not and a message which can contain positive or negative message.

With this object I can send any type of data from the Web API to the client along with the status. The client on receiving this message can check the status before processing the data. But I want to preprocess this on the client so that I have generic code that process all responses from the server.

Angular’s interceptor in instrumental for my scenario. It enable me to intercept the http response from the server and preprocess it before my page gets the response. Here is my code which processes the http response from REST service

    function response(response) {
        //checking whether we got our AjaxModel
        if (response.data.hasOwnProperty("Success") && response.data.hasOwnProperty("Message") && response.data.hasOwnProperty("Model")) {
            if (response.data.Success === false) {
                //as needed show error message to the user
                //reject the response
                return $q.reject(response);
            }
            else {
                response.data = response.data.Model;
            }
        }

        // Return the response or promise.
        return response || $q.when(response);
    }

As you see I am checking the response from server and if the Success flag is true I am rejecting the response. This response will be captured using the error callback. Here is the client code which internally uses the interceptor

    return $http.get("/api/contact")
        .success(function (data) {
            service.model = data;
        })
    .error(function (data) {
        //process error if needed
    });

Using Angular’s interceptor we intercepted our http response and preprocessed it. In addition this we can use the interceptor to catch the request, request error and response error. Here is the code of this interceptor.

'use strict';
angular.module('appinterceptors').factory('WebAPIInterceptor', WebAPIInterceptor);
WebAPIInterceptor.$inject = ['$q'];

function WebAPIInterceptor($q) {

    return {
        request: request,
        requestError: requestError,
        response: response,
        responseError: responseError
    };

    //request success
    function request(config) {

        // Return the config or promise.
        return config || $q.when(config);
    }

    //request error
    function requestError(rejection) {

        // Return the promise rejection.
        return $q.reject(rejection);
    }

    // response success
    function response(response) {
        //checking whether we got our AjaxModel
        if (response.data.hasOwnProperty("Success") && response.data.hasOwnProperty("Message") && response.data.hasOwnProperty("Model")) {
            if (response.data.Success === false) {
                //as needed show error message to the user
                //reject the response
                return $q.reject(response);
            }
            else {
                response.data = response.data.Model;
            }
        }

        // Return the response or promise.
        return response || $q.when(response);
    }

    //response Error
    function responseError(rejection) {
        // Return the promise rejection.
        return $q.reject(rejection);
    }
}

For a working code of this interceptor please go to my GitHub or take a look at the Gist.

No comments:

Post a Comment