I use a angular $http interceptor, to check if a ajax request returns 401 (not authenticated). If response is 401, the original request gets queued, a login form is shown and after login successfully, it retries the queued requests. This already works with $http, and the source for the angular interceptor is:
define('common.service.security.interceptor', ['angular'], function() {
'use strict';
angular.module('common.service.security.interceptor', ['common.service.security.retryQueue'])
.factory('securityInterceptor', [
    '$injector',
    '$location',
    'securityRetryQueue',
    function($injector, $location, securityRetryQueue) {
        return function(promise) {
            var $http = $injector.get('$http');
            // catch the erroneous requests
            return promise.then(null, function(originalResponse){
                if(originalResponse.status === 401){
                    promise = securityRetryQueue.pushRetryFn('Unauthorized', function retryRequest(){
                        return $injector.get('$http')(originalResponse.config);
                    });
                }
                 return promise;
            });
        };
    }
])
// register the interceptor to the angular http service. method)
.config(['$httpProvider', function($httpProvider) {
    $httpProvider.responseInterceptors.push('securityInterceptor');
}]);});
How can I make breeze request using this angular $http interceptor?
Breeze provides a wrapper for the angular $http service in the file "Breeze/Adapters/breeze.ajax.angular.js". So the first idea was to tell breeze to use it:
breeze.config.initializeAdapterInstance("ajax", "angular", true);
Debugging angular.js, it shows that breeze now in fact uses $http, but it does not execute the above registered interceptor. Inside $http, there is an array "reversedInterceptors", which holds the registered interceptors. I log this array to console. If i use $http, the length of this array is one (as expected), but when making request with breeze, this array is empty.
The question is, how can i use this $http interceptor with breeze requests?
Here is the code for breeze.ajax.angular.js, provided by breeze
define('breeze.ajax.angular.module', ['breeze', 'angular'], function (breeze) {
'use strict';
/* jshint ignore:start */
var core = breeze.core;
var httpService;
var rootScope;
var ctor = function () {
    this.name = "angular";
    this.defaultSettings = {};
};
ctor.prototype.initialize = function () {
    var ng = core.requireLib("angular");
    if (ng) {
        var $injector = ng.injector(['ng']);
        $injector.invoke(['$http', '$rootScope',
            function (xHttp, xRootScope) {
                httpService = xHttp;
                rootScope = xRootScope;
        }]);
    }
};
ctor.prototype.setHttp = function (http) {
    httpService = http;
    rootScope = null; // to suppress rootScope.digest
};
ctor.prototype.ajax = function (config) {
    if (!httpService) {
        throw new Error("Unable to locate angular for ajax adapter");
    }
    var ngConfig = {
        method: config.type,
        url: config.url,
        dataType: config.dataType,
        contentType: config.contentType,
        crossDomain: config.crossDomain
    }
    if (config.params) {
        // Hack: because of the way that Angular handles writing parameters out to the url.
        // so this approach takes over the url param writing completely.
        // See: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
        var delim = (ngConfig.url.indexOf("?") >= 0) ? "&" : "?";
        ngConfig.url = ngConfig.url + delim + encodeParams(config.params);
    }
    if (config.data) {
        ngConfig.data = config.data;
    }
    if (!core.isEmpty(this.defaultSettings)) {
        var compositeConfig = core.extend({}, this.defaultSettings);
        ngConfig = core.extend(compositeConfig, ngConfig);
    }
    httpService(ngConfig).success(function (data, status, headers, xconfig) {
        // HACK: because $http returns a server side null as a string containing "null" - this is WRONG.
        if (data === "null") data = null;
        var httpResponse = {
            data: data,
            status: status,
            getHeaders: headers,
            config: config
        };
        config.success(httpResponse);
    }).error(function (data, status, headers, xconfig) {
        var httpResponse = {
            data: data,
            status: status,
            getHeaders: headers,
            config: config
        };
        config.error(httpResponse);
    });
    rootScope && rootScope.$digest();
};
function encodeParams(obj) {
    var query = '';
    var key, subValue, innerObj;
    for (var name in obj) {
        var value = obj[name];
        if (value instanceof Array) {
            for (var i = 0; i < value.length; ++i) {
                subValue = value[i];
                fullSubName = name + '[' + i + ']';
                innerObj = {};
                innerObj[fullSubName] = subValue;
                query += encodeParams(innerObj) + '&';
            }
        } else if (value instanceof Object) {
            for (var subName in value) {
                subValue = value[subName];
                fullSubName = name + '[' + subName + ']';
                innerObj = {};
                innerObj[fullSubName] = subValue;
                query += encodeParams(innerObj) + '&';
            }
        } else if (value !== undefined) {
            query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
        }
    }
    return query.length ? query.substr(0, query.length - 1) : query;
}
breeze.config.registerAdapter("ajax", ctor);
breeze.config.initializeAdapterInstance("ajax", "angular", true);
/* jshint ignore:end */
});
                using the setHttp method works for me to use http interceptors with the breeze angular ajax adapter. in my environment, it looks like this:
(function() {
    'use strict';
    var serviceId = 'entityManagerFactory';
    angular.module('app').factory(serviceId, ['$http', emFactory]);
    function emFactory($http) {
        var instance = breeze.config.initializeAdapterInstance("ajax", "angular");
        instance.setHttp($http);
        ...
    }
})();
the only place I've really found any information about this is in the release notes for 1.4.4 on the download page. I don't really understand what this does. i'm sure one of the breeze guys will have a better explanation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With