From ad4336f9359a073e272930f8f9bcd36587a8648f Mon Sep 17 00:00:00 2001 From: Caitlin Potter Date: Sat, 26 Apr 2014 22:22:16 -0400 Subject: [PATCH] chore($http): remove deprecated responseInterceptors functionality Code cleanup! response interceptors have been deprecated for some time, and it is confusing to have two APIs, one of which is slightly "hidden" and hard to see, which perform the same task. The newer API is a bit cleaner and more visible, so this is naturally preferred. BREAKING CHANGE: Previously, it was possible to register a response interceptor like so: // register the interceptor as a service $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) { return function(promise) { return promise.then(function(response) { // do something on success return response; }, function(response) { // do something on error if (canRecover(response)) { return responseOrNewPromise } return $q.reject(response); }); } }); $httpProvider.responseInterceptors.push('myHttpInterceptor'); Now, one must use the newer API introduced in v1.1.4 (4ae46814), like so: $provide.factory('myHttpInterceptor', function($q) { return { response: function(response) { // do something on success return response; }, responseError: function(response) { // do something on error if (canRecover(response)) { return responseOrNewPromise } return $q.reject(response); } }; }); $httpProvider.interceptors.push('myHttpInterceptor'); More details on the new interceptors API (which has been around as of v1.1.4) can be found at https://docs.angularjs.org/api/ng/service/$http#interceptors Closes #7266 Closes #7267 --- src/ng/http.js | 72 -------------------------- test/ng/httpSpec.js | 122 +------------------------------------------- 2 files changed, 1 insertion(+), 193 deletions(-) diff --git a/src/ng/http.js b/src/ng/http.js index 0c86a0b7fe4b..61c7e8bae6cf 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -126,12 +126,6 @@ function $HttpProvider() { */ var interceptorFactories = this.interceptors = []; - /** - * For historical reasons, response interceptors are ordered by the order in which - * they are applied to the response. (This is the opposite of interceptorFactories) - */ - var responseInterceptorFactories = this.responseInterceptors = []; - this.$get = ['$httpBackend', '$browser', '$cacheFactory', '$rootScope', '$q', '$injector', function($httpBackend, $browser, $cacheFactory, $rootScope, $q, $injector) { @@ -149,27 +143,6 @@ function $HttpProvider() { ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory)); }); - forEach(responseInterceptorFactories, function(interceptorFactory, index) { - var responseFn = isString(interceptorFactory) - ? $injector.get(interceptorFactory) - : $injector.invoke(interceptorFactory); - - /** - * Response interceptors go before "around" interceptors (no real reason, just - * had to pick one.) But they are already reversed, so we can't use unshift, hence - * the splice. - */ - reversedInterceptors.splice(index, 0, { - response: function(response) { - return responseFn($q.when(response)); - }, - responseError: function(response) { - return responseFn($q.reject(response)); - } - }); - }); - - /** * @ngdoc service * @kind function @@ -422,51 +395,6 @@ function $HttpProvider() { * }); * ``` * - * # Response interceptors (DEPRECATED) - * - * Before you start creating interceptors, be sure to understand the - * {@link ng.$q $q and deferred/promise APIs}. - * - * For purposes of global error handling, authentication or any kind of synchronous or - * asynchronous preprocessing of received responses, it is desirable to be able to intercept - * responses for http requests before they are handed over to the application code that - * initiated these requests. The response interceptors leverage the {@link ng.$q - * promise apis} to fulfil this need for both synchronous and asynchronous preprocessing. - * - * The interceptors are service factories that are registered with the $httpProvider by - * adding them to the `$httpProvider.responseInterceptors` array. The factory is called and - * injected with dependencies (if specified) and returns the interceptor — a function that - * takes a {@link ng.$q promise} and returns the original or a new promise. - * - * ```js - * // register the interceptor as a service - * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) { - * return function(promise) { - * return promise.then(function(response) { - * // do something on success - * return response; - * }, function(response) { - * // do something on error - * if (canRecover(response)) { - * return responseOrNewPromise - * } - * return $q.reject(response); - * }); - * } - * }); - * - * $httpProvider.responseInterceptors.push('myHttpInterceptor'); - * - * - * // register the interceptor via an anonymous factory - * $httpProvider.responseInterceptors.push(function($q, dependency1, dependency2) { - * return function(promise) { - * // same as above - * } - * }); - * ``` - * - * * # Security Considerations * * When designing web applications, consider security threats from: diff --git a/test/ng/httpSpec.js b/test/ng/httpSpec.js index f93b2d1a484e..27017061635c 100644 --- a/test/ng/httpSpec.js +++ b/test/ng/httpSpec.js @@ -28,29 +28,6 @@ describe('$http', function() { describe('$httpProvider', function() { describe('interceptors', function() { - it('should accept injected rejected response interceptor', function() { - var wasCalled = false; - module(function($httpProvider, $provide) { - $httpProvider.responseInterceptors.push('injectedInterceptor'); - $provide.factory('injectedInterceptor', ['$q', function($q) { - return function(promise) { - return promise.then(null, function authInterceptor(response) { - wasCalled = true; - expect(response.status).toEqual(401); - return $q.reject(response); - }); - }; - }]); - }); - inject(function($http, $httpBackend) { - $httpBackend.expect('GET', '/url').respond(401); - $http({method: 'GET', url: '/url'}); - $httpBackend.flush(); - expect(wasCalled).toEqual(true); - }); - }); - - it('should chain request, requestReject, response and responseReject interceptors', function() { module(function($httpProvider) { var savedConfig, savedResponse; @@ -128,28 +105,6 @@ describe('$http', function() { } }; }); - $httpProvider.responseInterceptors.push(function($q) { - return function(promise) { - var defer = $q.defer(); - - promise.then(function(response) { - response.data = '[' + response.data + '] legacy-1'; - defer.resolve(response); - }); - return defer.promise; - }; - }); - $httpProvider.responseInterceptors.push(function($q) { - return function(promise) { - var defer = $q.defer(); - - promise.then(function(response) { - response.data = '[' + response.data + '] legacy-2'; - defer.resolve(response); - }); - return defer.promise; - }; - }); }); inject(function($http, $httpBackend) { var response; @@ -158,82 +113,7 @@ describe('$http', function() { response = r; }); $httpBackend.flush(); - expect(response.data).toEqual('{{[[response] legacy-1] legacy-2} inner} outer'); - }); - }); - }); - - - describe('response interceptors', function() { - - it('should default to an empty array', module(function($httpProvider) { - expect($httpProvider.responseInterceptors).toEqual([]); - })); - - - it('should pass the responses through interceptors', function() { - module(function($httpProvider, $provide) { - $provide.factory('testInterceptor', function ($q) { - return function(httpPromise) { - return httpPromise.then(function(response) { - var deferred = $q.defer(); - deferred.resolve({ - data: response.data + '?', - status: 209, - headers: response.headers, - request: response.config - }); - return deferred.promise; - }); - }; - }); - // just change the response data and pass the response object along - $httpProvider.responseInterceptors.push(function() { - return function(httpPromise) { - return httpPromise.then(function(response) { - response.data += '!'; - return response; - }); - }; - }); - - // return a new resolved promise representing modified response object - $httpProvider.responseInterceptors.push('testInterceptor'); - }); - inject(function($http, $httpBackend) { - $httpBackend.expect('GET', '/foo').respond(201, 'Hello'); - $http.get('/foo').success(function(data, status) { - expect(data).toBe('Hello!?'); - expect(status).toBe(209); - callback(); - }); - $httpBackend.flush(); - expect(callback).toHaveBeenCalledOnce(); - }); - }); - - - it('should support interceptors defined as services', function() { - module(function($provide, $httpProvider) { - $provide.factory('myInterceptor', function() { - return function(promise) { - return promise.then(function(response) { - response.data = uppercase(response.data); - return response; - }); - }; - }); - $httpProvider.responseInterceptors.push('myInterceptor'); - }); - inject(function($http, $httpBackend) { - var response; - - $httpBackend.expect('GET', '/test').respond('hello!'); - $http.get('/test').success(function(data) {response = data;}); - expect(response).toBeUndefined(); - - $httpBackend.flush(); - expect(response).toBe('HELLO!'); + expect(response.data).toEqual('{{response} inner} outer'); }); }); });