From 56c861c9e114c45790865e5635eaae8d32eb649a Mon Sep 17 00:00:00 2001 From: Chris Chua Date: Wed, 22 Jul 2015 00:10:59 -0700 Subject: [PATCH] feat($http): support handling additional XHR events Closes #11547 Closes #1934 --- src/ng/http.js | 4 +++- src/ng/httpBackend.js | 16 +++++++++++++++- src/ngMock/angular-mocks.js | 11 +++++++++++ test/ng/httpBackendSpec.js | 15 +++++++++++++++ 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/ng/http.js b/src/ng/http.js index 6640a1219e2a..295ba68263e8 100644 --- a/src/ng/http.js +++ b/src/ng/http.js @@ -801,6 +801,8 @@ function $HttpProvider() { * - **headers** – `{Object}` – Map of strings or functions which return strings representing * HTTP headers to send to the server. If the return value of a function is null, the * header will not be sent. Functions accept a config object as an argument. + * - **events** - `{Object}` - Event listeners to be bound to the XMLHttpRequest object. + * To bind events to the XMLHttpRequest upload object, nest it under the upload key. * - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token. * - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token. * - **transformRequest** – @@ -1259,7 +1261,7 @@ function $HttpProvider() { } $httpBackend(config.method, url, reqData, done, reqHeaders, config.timeout, - config.withCredentials, config.responseType); + config.withCredentials, config.responseType, config.events); } return promise; diff --git a/src/ng/httpBackend.js b/src/ng/httpBackend.js index 0b16b34a7748..b961874ee329 100644 --- a/src/ng/httpBackend.js +++ b/src/ng/httpBackend.js @@ -54,7 +54,7 @@ function $HttpBackendProvider() { function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDocument) { // TODO(vojta): fix the signature - return function(method, url, post, callback, headers, timeout, withCredentials, responseType) { + return function(method, url, post, callback, headers, timeout, withCredentials, responseType, eventHandlers) { $browser.$$incOutstandingRequestCount(); url = url || $browser.url(); @@ -114,6 +114,20 @@ function createHttpBackend($browser, createXhr, $browserDefer, callbacks, rawDoc xhr.onerror = requestError; xhr.onabort = requestError; + if (eventHandlers) { + forEach(eventHandlers, function(value, key) { + if (key !== 'upload') { + xhr.addEventListener(key, value); + } + }); + + if (eventHandlers.upload) { + forEach(eventHandlers.upload, function(value, key) { + xhr.upload.addEventListener(key, value); + }); + } + } + if (withCredentials) { xhr.withCredentials = true; } diff --git a/src/ngMock/angular-mocks.js b/src/ngMock/angular-mocks.js index 637beb1c7451..b068d0d32079 100644 --- a/src/ngMock/angular-mocks.js +++ b/src/ngMock/angular-mocks.js @@ -2009,6 +2009,17 @@ function MockXhr() { }; this.abort = angular.noop; + + this.$$events = {}; + this.addEventListener = function(name, listener) { + if (angular.isUndefined(this.$$events[name])) this.$$events[name] = []; + this.$$events[name].push(listener); + }; + + this.upload = { + $$events: {}, + addEventListener: this.addEventListener + }; } diff --git a/test/ng/httpBackendSpec.js b/test/ng/httpBackendSpec.js index 5dbb6cfdff2b..a0ec76dd8e19 100644 --- a/test/ng/httpBackendSpec.js +++ b/test/ng/httpBackendSpec.js @@ -241,6 +241,21 @@ describe('$httpBackend', function() { }); + it('should set up event listeners', function() { + var progressFn = function() {}; + var uploadProgressFn = function() {}; + $backend('GET', '/url', null, callback, {}, null, null, null, { + progress: progressFn, + upload: { + progress: uploadProgressFn + } + }); + xhr = MockXhr.$$lastInstance; + expect(xhr.$$events.progress[0]).toBe(progressFn); + expect(xhr.upload.$$events.progress[0]).toBe(uploadProgressFn); + }); + + describe('responseType', function() { it('should set responseType and return xhr.response', function() {