feat(http): refactor library to work in dart
Mostly internal refactoring needed to make ts2dart and DartAnalyzer happy. Fixes #2415
This commit is contained in:
@ -1,9 +1,11 @@
|
||||
library angular2.src.http.backends.browser_xhr;
|
||||
|
||||
/// import 'dart:html' show HttpRequest;
|
||||
/// import 'package:angular2/di.dart';
|
||||
import 'dart:html' show HttpRequest;
|
||||
import 'package:angular2/di.dart';
|
||||
|
||||
/// @Injectable()
|
||||
/// class BrowserXHR {
|
||||
/// factory BrowserXHR() => new HttpRequest();
|
||||
/// }
|
||||
@Injectable()
|
||||
class BrowserXHR {
|
||||
HttpRequest build() {
|
||||
return new HttpRequest();
|
||||
}
|
||||
}
|
||||
|
@ -5,5 +5,6 @@ import {Injectable} from 'angular2/di';
|
||||
// Make sure not to evaluate this in a non-browser environment!
|
||||
@Injectable()
|
||||
export class BrowserXHR {
|
||||
constructor() { return <any>(new window.XMLHttpRequest()); }
|
||||
constructor() {}
|
||||
build(): any { return <any>(new window.XMLHttpRequest()); }
|
||||
}
|
||||
|
@ -3,7 +3,9 @@ import {Request} from 'angular2/src/http/static_request';
|
||||
import {Response} from 'angular2/src/http/static_response';
|
||||
import {ReadyStates} from 'angular2/src/http/enums';
|
||||
import {Connection, ConnectionBackend} from 'angular2/src/http/interfaces';
|
||||
import * as Rx from 'rx';
|
||||
import {ObservableWrapper, EventEmitter} from 'angular2/src/facade/async';
|
||||
import {isPresent} from 'angular2/src/facade/lang';
|
||||
import {IMPLEMENTS, BaseException} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
*
|
||||
@ -14,7 +16,8 @@ import * as Rx from 'rx';
|
||||
* {@link MockBackend} in order to mock responses to requests.
|
||||
*
|
||||
**/
|
||||
export class MockConnection implements Connection {
|
||||
@IMPLEMENTS(Connection)
|
||||
export class MockConnection {
|
||||
// TODO Name `readyState` should change to be more generic, and states could be made to be more
|
||||
// descriptive than XHR states.
|
||||
/**
|
||||
@ -33,18 +36,12 @@ export class MockConnection implements Connection {
|
||||
* Observable](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/observable.md)
|
||||
* of {@link Response}. Can be subscribed to in order to be notified when a response is available.
|
||||
*/
|
||||
response: Rx.Subject<Response>;
|
||||
response: EventEmitter;
|
||||
|
||||
constructor(req: Request) {
|
||||
if (Rx.hasOwnProperty('default')) {
|
||||
this.response = new ((<any>Rx).default.Rx.Subject)();
|
||||
} else {
|
||||
this.response = new Rx.Subject<Response>();
|
||||
}
|
||||
|
||||
this.response = new EventEmitter();
|
||||
this.readyState = ReadyStates.OPEN;
|
||||
this.request = req;
|
||||
this.dispose = this.dispose.bind(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,12 +68,12 @@ export class MockConnection implements Connection {
|
||||
*
|
||||
*/
|
||||
mockRespond(res: Response) {
|
||||
if (this.readyState >= ReadyStates.DONE) {
|
||||
throw new Error('Connection has already been resolved');
|
||||
if (this.readyState === ReadyStates.DONE || this.readyState === ReadyStates.CANCELLED) {
|
||||
throw new BaseException('Connection has already been resolved');
|
||||
}
|
||||
this.readyState = ReadyStates.DONE;
|
||||
this.response.onNext(res);
|
||||
this.response.onCompleted();
|
||||
ObservableWrapper.callNext(this.response, res);
|
||||
ObservableWrapper.callReturn(this.response);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,8 +97,8 @@ export class MockConnection implements Connection {
|
||||
mockError(err?) {
|
||||
// Matches XHR semantics
|
||||
this.readyState = ReadyStates.DONE;
|
||||
this.response.onError(err);
|
||||
this.response.onCompleted();
|
||||
ObservableWrapper.callThrow(this.response, err);
|
||||
ObservableWrapper.callReturn(this.response);
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +134,8 @@ export class MockConnection implements Connection {
|
||||
* This method only exists in the mock implementation, not in real Backends.
|
||||
**/
|
||||
@Injectable()
|
||||
export class MockBackend implements ConnectionBackend {
|
||||
@IMPLEMENTS(ConnectionBackend)
|
||||
export class MockBackend {
|
||||
/**
|
||||
* [RxJS
|
||||
* Subject](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md)
|
||||
@ -171,7 +169,7 @@ export class MockBackend implements ConnectionBackend {
|
||||
*
|
||||
* This property only exists in the mock implementation, not in real Backends.
|
||||
*/
|
||||
connections: Rx.Subject<MockConnection>;
|
||||
connections: EventEmitter; //<MockConnection>
|
||||
|
||||
/**
|
||||
* An array representation of `connections`. This array will be updated with each connection that
|
||||
@ -188,20 +186,14 @@ export class MockBackend implements ConnectionBackend {
|
||||
*
|
||||
* This property only exists in the mock implementation, not in real Backends.
|
||||
*/
|
||||
pendingConnections: Rx.Observable<MockConnection>;
|
||||
pendingConnections: EventEmitter; //<MockConnection>
|
||||
constructor() {
|
||||
var Observable;
|
||||
this.connectionsArray = [];
|
||||
if (Rx.hasOwnProperty('default')) {
|
||||
this.connections = new (<any>Rx).default.Rx.Subject();
|
||||
Observable = (<any>Rx).default.Rx.Observable;
|
||||
} else {
|
||||
this.connections = new Rx.Subject<MockConnection>();
|
||||
Observable = Rx.Observable;
|
||||
}
|
||||
this.connections.subscribe(connection => this.connectionsArray.push(connection));
|
||||
this.pendingConnections =
|
||||
Observable.fromArray(this.connectionsArray).filter((c) => c.readyState < ReadyStates.DONE);
|
||||
this.connections = new EventEmitter();
|
||||
ObservableWrapper.subscribe(this.connections,
|
||||
connection => this.connectionsArray.push(connection));
|
||||
this.pendingConnections = new EventEmitter();
|
||||
// Observable.fromArray(this.connectionsArray).filter((c) => c.readyState < ReadyStates.DONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -211,8 +203,8 @@ export class MockBackend implements ConnectionBackend {
|
||||
*/
|
||||
verifyNoPendingRequests() {
|
||||
let pending = 0;
|
||||
this.pendingConnections.subscribe((c) => pending++);
|
||||
if (pending > 0) throw new Error(`${pending} pending connections to be resolved`);
|
||||
ObservableWrapper.subscribe(this.pendingConnections, c => pending++);
|
||||
if (pending > 0) throw new BaseException(`${pending} pending connections to be resolved`);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -221,7 +213,7 @@ export class MockBackend implements ConnectionBackend {
|
||||
*
|
||||
* This method only exists in the mock implementation, not in real Backends.
|
||||
*/
|
||||
resolveAllConnections() { this.connections.subscribe((c) => c.readyState = 4); }
|
||||
resolveAllConnections() { ObservableWrapper.subscribe(this.connections, c => c.readyState = 4); }
|
||||
|
||||
/**
|
||||
* Creates a new {@link MockConnection}. This is equivalent to calling `new
|
||||
@ -229,12 +221,12 @@ export class MockBackend implements ConnectionBackend {
|
||||
* observable of this `MockBackend` instance. This method will usually only be used by tests
|
||||
* against the framework itself, not by end-users.
|
||||
*/
|
||||
createConnection(req: Request): Connection {
|
||||
if (!req || !(req instanceof Request)) {
|
||||
throw new Error(`createConnection requires an instance of Request, got ${req}`);
|
||||
createConnection(req: Request) {
|
||||
if (!isPresent(req) || !(req instanceof Request)) {
|
||||
throw new BaseException(`createConnection requires an instance of Request, got ${req}`);
|
||||
}
|
||||
let connection = new MockConnection(req);
|
||||
this.connections.onNext(connection);
|
||||
ObservableWrapper.callNext(this.connections, connection);
|
||||
return connection;
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,11 @@
|
||||
import {ConnectionBackend, Connection} from '../interfaces';
|
||||
import {ReadyStates, RequestMethods} from '../enums';
|
||||
import {ReadyStates, RequestMethods, RequestMethodsMap} from '../enums';
|
||||
import {Request} from '../static_request';
|
||||
import {Response} from '../static_response';
|
||||
import {Inject} from 'angular2/di';
|
||||
import {Injectable} from 'angular2/di';
|
||||
import {BrowserXHR} from './browser_xhr';
|
||||
import * as Rx from 'rx';
|
||||
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
|
||||
import {isPresent, ENUM_INDEX} from 'angular2/src/facade/lang';
|
||||
|
||||
/**
|
||||
* Creates connections using `XMLHttpRequest`. Given a fully-qualified
|
||||
@ -22,22 +22,24 @@ export class XHRConnection implements Connection {
|
||||
* [Subject](https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/subject.md)
|
||||
* which emits a single {@link Response} value on load event of `XMLHttpRequest`.
|
||||
*/
|
||||
response: Rx.Subject<Response>;
|
||||
response: EventEmitter; //<Response>;
|
||||
readyState: ReadyStates;
|
||||
private _xhr;
|
||||
constructor(req: Request, NativeConstruct: any) {
|
||||
constructor(req: Request, browserXHR: BrowserXHR) {
|
||||
// TODO: get rid of this when enum lookups are available in ts2dart
|
||||
// https://github.com/angular/ts2dart/issues/221
|
||||
var requestMethodsMap = new RequestMethodsMap();
|
||||
this.request = req;
|
||||
if (Rx.hasOwnProperty('default')) {
|
||||
this.response = new (<any>Rx).default.Rx.Subject();
|
||||
} else {
|
||||
this.response = new Rx.Subject<Response>();
|
||||
}
|
||||
this._xhr = new NativeConstruct();
|
||||
this.response = new EventEmitter();
|
||||
this._xhr = browserXHR.build();
|
||||
// TODO(jeffbcross): implement error listening/propagation
|
||||
this._xhr.open(RequestMethods[req.method], req.url);
|
||||
this._xhr.open(requestMethodsMap.getMethod(ENUM_INDEX(req.method)), req.url);
|
||||
this._xhr.addEventListener(
|
||||
'load',
|
||||
() => {this.response.onNext(new Response(this._xhr.response || this._xhr.responseText))});
|
||||
(_) => {ObservableWrapper.callNext(
|
||||
this.response, new Response({
|
||||
body: isPresent(this._xhr.response) ? this._xhr.response : this._xhr.responseText
|
||||
}))});
|
||||
// TODO(jeffbcross): make this more dynamic based on body type
|
||||
this._xhr.send(this.request.text());
|
||||
}
|
||||
@ -76,8 +78,8 @@ export class XHRConnection implements Connection {
|
||||
**/
|
||||
@Injectable()
|
||||
export class XHRBackend implements ConnectionBackend {
|
||||
constructor(private _NativeConstruct: BrowserXHR) {}
|
||||
constructor(private _browserXHR: BrowserXHR) {}
|
||||
createConnection(request: Request): XHRConnection {
|
||||
return new XHRConnection(request, this._NativeConstruct);
|
||||
return new XHRConnection(request, this._browserXHR);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user