Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 15 additions & 2 deletions modules/angular2/src/http/backends/xhr_backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,21 @@ export class XHRConnection implements Connection {
// TODO(jeffbcross): implement error listening/propagation
this._xhr.open(requestMethodsMap.getMethod(ENUM_INDEX(req.method)), req.url);
this._xhr.addEventListener('load', (_) => {
var responseOptions = new ResponseOptions(
{body: isPresent(this._xhr.response) ? this._xhr.response : this._xhr.responseText});
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
let response = isPresent(this._xhr.response) ? this._xhr.response : this._xhr.responseText;

// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
let status = this._xhr.status === 1223 ? 204 : this._xhr.status;

// fix status code when it is 0 (0 status is undocumented).
// Occurs when accessing file resources or on Android 4.1 stock browser
// while retrieving files from application cache.
if (status === 0) {
status = response ? 200 : 0;
}

var responseOptions = new ResponseOptions({body: response, status: status});
if (isPresent(baseResponseOptions)) {
responseOptions = baseResponseOptions.merge(responseOptions);
}
Expand Down
3 changes: 2 additions & 1 deletion modules/angular2/src/render/xhr_impl.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {Injectable} from 'angular2/di';
import {Promise, PromiseWrapper, PromiseCompleter} from 'angular2/src/facade/async';
import {isPresent} from 'angular2/src/facade/lang';
import {XHR} from './xhr';

@Injectable()
Expand All @@ -13,7 +14,7 @@ export class XHRImpl extends XHR {
xhr.onload = function() {
// responseText is the old-school way of retrieving response (supported by IE8 & 9)
// response/responseType properties were introduced in XHR Level2 spec (supported by IE10)
var response = ('response' in xhr) ? xhr.response : xhr.responseText;
var response = isPresent(xhr.response) ? xhr.response : xhr.responseText;

// normalize IE9 bug (http://bugs.jquery.com/ticket/1450)
var status = xhr.status === 1223 ? 204 : xhr.status;
Expand Down
62 changes: 62 additions & 0 deletions modules/angular2/test/http/backends/xhr_backend_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ class MockBrowserXHR extends BrowserXhr {
responseText: string;
setRequestHeader: any;
callbacks: Map<string, Function>;
status: number;
constructor() {
super();
var spy = new SpyObject();
Expand All @@ -49,6 +50,12 @@ class MockBrowserXHR extends BrowserXhr {
this.callbacks = new Map();
}

setStatusCode(status) { this.status = status; }

setResponse(value) { this.response = value; }

setResponseText(value) { this.responseText = value; }

addEventListener(type: string, cb: Function) { this.callbacks.set(type, cb); }

dispatchEvent(type: string) { this.callbacks.get(type)({}); }
Expand Down Expand Up @@ -125,6 +132,61 @@ export function main() {
expect(setRequestHeaderSpy).toHaveBeenCalledWith('Content-Type', ['text/xml']);
expect(setRequestHeaderSpy).toHaveBeenCalledWith('Breaking-Bad', ['<3']);
});

it('should return the correct status code', inject([AsyncTestCompleter], async => {
var statusCode = 418;
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
new ResponseOptions({status: statusCode}));

ObservableWrapper.subscribe<Response>(connection.response, res => {
expect(res.status).toBe(statusCode);
async.done();
});

existingXHRs[0].setStatusCode(statusCode);
existingXHRs[0].dispatchEvent('load');
}));

it('should normalize IE\'s 1223 status code into 204', inject([AsyncTestCompleter], async => {
var statusCode = 1223;
var normalizedCode = 204;
var connection = new XHRConnection(sampleRequest, new MockBrowserXHR(),
new ResponseOptions({status: statusCode}));

ObservableWrapper.subscribe<Response>(connection.response, res => {
expect(res.status).toBe(normalizedCode);
async.done();
});

existingXHRs[0].setStatusCode(statusCode);
existingXHRs[0].dispatchEvent('load');
}));

it('should normalize responseText and response', inject([AsyncTestCompleter], async => {
var responseBody = 'Doge';

var connection1 =
new XHRConnection(sampleRequest, new MockBrowserXHR(), new ResponseOptions());

var connection2 =
new XHRConnection(sampleRequest, new MockBrowserXHR(), new ResponseOptions());

ObservableWrapper.subscribe<Response>(connection1.response, res => {
expect(res.text()).toBe(responseBody);

ObservableWrapper.subscribe<Response>(connection2.response, ress => {
expect(ress.text()).toBe(responseBody);
async.done();
});
existingXHRs[1].dispatchEvent('load');
});

existingXHRs[0].setResponseText(responseBody);
existingXHRs[1].setResponse(responseBody);

existingXHRs[0].dispatchEvent('load');
}));

});
});
}