parent
93596dff3f
commit
b68e561c0f
|
@ -2,10 +2,14 @@ import {bind, Binding} from 'angular2/di';
|
||||||
import {Http, HttpFactory} from './src/http/http';
|
import {Http, HttpFactory} from './src/http/http';
|
||||||
import {XHRBackend} from 'angular2/src/http/backends/xhr_backend';
|
import {XHRBackend} from 'angular2/src/http/backends/xhr_backend';
|
||||||
import {BrowserXHR} from 'angular2/src/http/backends/browser_xhr';
|
import {BrowserXHR} from 'angular2/src/http/backends/browser_xhr';
|
||||||
|
import {BaseRequestOptions} from 'angular2/src/http/base_request_options';
|
||||||
|
|
||||||
export {Http};
|
export {Http};
|
||||||
export var httpInjectables: List<any> = [
|
export var httpInjectables: List<any> = [
|
||||||
|
bind(BrowserXHR)
|
||||||
|
.toValue(BrowserXHR),
|
||||||
XHRBackend,
|
XHRBackend,
|
||||||
bind(BrowserXHR).toValue(BrowserXHR),
|
BaseRequestOptions,
|
||||||
bind(Http).toFactory(HttpFactory, [XHRBackend])
|
bind(HttpFactory).toFactory(HttpFactory, [XHRBackend, BaseRequestOptions]),
|
||||||
|
Http
|
||||||
];
|
];
|
||||||
|
|
|
@ -6,10 +6,10 @@ import {RequestOptions} from './interfaces';
|
||||||
import {Injectable} from 'angular2/di';
|
import {Injectable} from 'angular2/di';
|
||||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
|
|
||||||
export class RequestOptionsClass {
|
export class RequestOptionsClass implements RequestOptions {
|
||||||
method: RequestMethods = RequestMethods.GET;
|
method: RequestMethods = RequestMethods.GET;
|
||||||
headers: Headers;
|
headers: Headers;
|
||||||
body: URLSearchParams | FormData | string;
|
body: URLSearchParams | FormData | Blob | string;
|
||||||
mode: RequestModesOpts = RequestModesOpts.Cors;
|
mode: RequestModesOpts = RequestModesOpts.Cors;
|
||||||
credentials: RequestCredentialsOpts;
|
credentials: RequestCredentialsOpts;
|
||||||
cache: RequestCacheOpts;
|
cache: RequestCacheOpts;
|
||||||
|
|
|
@ -5,7 +5,7 @@ export enum RequestCacheOpts {Default, NoStore, Reload, NoCache, ForceCache, Onl
|
||||||
|
|
||||||
export enum RequestCredentialsOpts {Omit, SameOrigin, Include};
|
export enum RequestCredentialsOpts {Omit, SameOrigin, Include};
|
||||||
|
|
||||||
export enum RequestMethods {GET, POST, PUT, DELETE, OPTIONS, HEAD};
|
export enum RequestMethods {GET, POST, PUT, DELETE, OPTIONS, HEAD, PATCH};
|
||||||
|
|
||||||
export enum ReadyStates {UNSENT, OPEN, HEADERS_RECEIVED, LOADING, DONE, CANCELLED};
|
export enum ReadyStates {UNSENT, OPEN, HEADERS_RECEIVED, LOADING, DONE, CANCELLED};
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import {Request} from './static_request';
|
||||||
import {Response} from './static_response';
|
import {Response} from './static_response';
|
||||||
import {XHRBackend} from './backends/xhr_backend';
|
import {XHRBackend} from './backends/xhr_backend';
|
||||||
import {BaseRequestOptions} from './base_request_options';
|
import {BaseRequestOptions} from './base_request_options';
|
||||||
|
import {RequestMethods} from './enums';
|
||||||
|
import {URLSearchParams} from './url_search_params';
|
||||||
import * as Rx from 'rx';
|
import * as Rx from 'rx';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,9 +45,59 @@ import * as Rx from 'rx';
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
function httpRequest(backend: XHRBackend, request: Request) {
|
||||||
|
return <Rx.Observable<Response>>(Observable.create(observer => {
|
||||||
|
var connection: Connection = backend.createConnection(request);
|
||||||
|
var internalSubscription = connection.response.subscribe(observer);
|
||||||
|
return () => {
|
||||||
|
internalSubscription.dispose();
|
||||||
|
connection.dispose();
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
// Abstract
|
// Abstract
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Http {
|
export class Http {
|
||||||
|
constructor(private backend: XHRBackend, private defaultOptions: BaseRequestOptions) {}
|
||||||
|
|
||||||
|
request(url: string, options?: RequestOptions): Rx.Observable<Response> {
|
||||||
|
return httpRequest(this.backend, new Request(url, this.defaultOptions.merge(options)));
|
||||||
|
}
|
||||||
|
|
||||||
|
get(url: string, options?: RequestOptions) {
|
||||||
|
return httpRequest(this.backend, new Request(url, this.defaultOptions.merge(options)
|
||||||
|
.merge({method: RequestMethods.GET})));
|
||||||
|
}
|
||||||
|
|
||||||
|
post(url: string, body: URLSearchParams | FormData | Blob | string, options?: RequestOptions) {
|
||||||
|
return httpRequest(this.backend,
|
||||||
|
new Request(url, this.defaultOptions.merge(options)
|
||||||
|
|
||||||
|
.merge({body: body, method: RequestMethods.POST})));
|
||||||
|
}
|
||||||
|
|
||||||
|
put(url: string, body: URLSearchParams | FormData | Blob | string, options?: RequestOptions) {
|
||||||
|
return httpRequest(this.backend,
|
||||||
|
new Request(url, this.defaultOptions.merge(options)
|
||||||
|
.merge({body: body, method: RequestMethods.PUT})));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete (url: string, options?: RequestOptions) {
|
||||||
|
return httpRequest(this.backend, new Request(url, this.defaultOptions.merge(options)
|
||||||
|
.merge({method: RequestMethods.DELETE})));
|
||||||
|
}
|
||||||
|
|
||||||
|
patch(url: string, body: URLSearchParams | FormData | Blob | string, options?: RequestOptions) {
|
||||||
|
return httpRequest(this.backend,
|
||||||
|
new Request(url, this.defaultOptions.merge(options)
|
||||||
|
.merge({body: body, method: RequestMethods.PATCH})));
|
||||||
|
}
|
||||||
|
|
||||||
|
head(url: string, options?: RequestOptions) {
|
||||||
|
return httpRequest(this.backend, new Request(url, this.defaultOptions.merge(options)
|
||||||
|
.merge({method: RequestMethods.HEAD})));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var Observable;
|
var Observable;
|
||||||
|
@ -56,13 +108,6 @@ if (Rx.hasOwnProperty('default')) {
|
||||||
}
|
}
|
||||||
export function HttpFactory(backend: XHRBackend, defaultOptions: BaseRequestOptions) {
|
export function HttpFactory(backend: XHRBackend, defaultOptions: BaseRequestOptions) {
|
||||||
return function(url: string, options?: RequestOptions) {
|
return function(url: string, options?: RequestOptions) {
|
||||||
return <Rx.Observable<Response>>(Observable.create(observer => {
|
return httpRequest(backend, new Request(url, defaultOptions.merge(options)));
|
||||||
var connection: Connection = backend.createConnection(new Request(url, options));
|
|
||||||
var internalSubscription = connection.response.subscribe(observer);
|
|
||||||
return () => {
|
|
||||||
internalSubscription.dispose();
|
|
||||||
connection.dispose();
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import {URLSearchParams} from './url_search_params';
|
||||||
export interface RequestOptions {
|
export interface RequestOptions {
|
||||||
method?: RequestMethods;
|
method?: RequestMethods;
|
||||||
headers?: Headers;
|
headers?: Headers;
|
||||||
body?: URLSearchParams | FormData | string;
|
body?: URLSearchParams | FormData | Blob | string;
|
||||||
mode?: RequestModesOpts;
|
mode?: RequestModesOpts;
|
||||||
credentials?: RequestCredentialsOpts;
|
credentials?: RequestCredentialsOpts;
|
||||||
cache?: RequestCacheOpts;
|
cache?: RequestCacheOpts;
|
||||||
|
|
|
@ -24,8 +24,8 @@ export function main() {
|
||||||
it('should retain previously merged values when merging again', () => {
|
it('should retain previously merged values when merging again', () => {
|
||||||
var options1 = new BaseRequestOptions();
|
var options1 = new BaseRequestOptions();
|
||||||
var options2 = options1.merge({method: RequestMethods.DELETE});
|
var options2 = options1.merge({method: RequestMethods.DELETE});
|
||||||
var options3 = options2.merge({mode: RequestModesOpts.NoCors}) expect(options3.mode)
|
var options3 = options2.merge({mode: RequestModesOpts.NoCors});
|
||||||
.toBe(RequestModesOpts.NoCors);
|
expect(options3.mode).toBe(RequestModesOpts.NoCors);
|
||||||
expect(options3.method).toBe(RequestMethods.DELETE);
|
expect(options3.method).toBe(RequestMethods.DELETE);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,11 +12,11 @@ import {
|
||||||
} from 'angular2/test_lib';
|
} from 'angular2/test_lib';
|
||||||
import {Http, HttpFactory} from 'angular2/src/http/http';
|
import {Http, HttpFactory} from 'angular2/src/http/http';
|
||||||
import {XHRBackend} from 'angular2/src/http/backends/xhr_backend';
|
import {XHRBackend} from 'angular2/src/http/backends/xhr_backend';
|
||||||
import {httpInjectables} from 'angular2/http';
|
|
||||||
import {Injector, bind} from 'angular2/di';
|
import {Injector, bind} from 'angular2/di';
|
||||||
import {MockBackend} from 'angular2/src/http/backends/mock_backend';
|
import {MockBackend} from 'angular2/src/http/backends/mock_backend';
|
||||||
import {Response} from 'angular2/src/http/static_response';
|
import {Response} from 'angular2/src/http/static_response';
|
||||||
import {ReadyStates} from 'angular2/src/http/enums';
|
import {RequestMethods} from 'angular2/src/http/enums';
|
||||||
|
import {BaseRequestOptions} from 'angular2/src/http/base_request_options';
|
||||||
|
|
||||||
class SpyObserver extends SpyObject {
|
class SpyObserver extends SpyObject {
|
||||||
onNext: Function;
|
onNext: Function;
|
||||||
|
@ -38,20 +38,31 @@ export function main() {
|
||||||
var backend: MockBackend;
|
var backend: MockBackend;
|
||||||
var baseResponse;
|
var baseResponse;
|
||||||
var sampleObserver;
|
var sampleObserver;
|
||||||
|
var httpFactory;
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
injector = Injector.resolveAndCreate(
|
injector = Injector.resolveAndCreate([
|
||||||
[MockBackend, bind(Http).toFactory(HttpFactory, [MockBackend])]);
|
BaseRequestOptions,
|
||||||
|
MockBackend,
|
||||||
|
bind(XHRBackend).toClass(MockBackend),
|
||||||
|
bind(HttpFactory).toFactory(HttpFactory, [MockBackend, BaseRequestOptions]),
|
||||||
|
bind(Http).toFactory(
|
||||||
|
function(backend: XHRBackend, defaultOptions: BaseRequestOptions) {
|
||||||
|
return new Http(backend, defaultOptions);
|
||||||
|
},
|
||||||
|
[MockBackend, BaseRequestOptions])
|
||||||
|
]);
|
||||||
http = injector.get(Http);
|
http = injector.get(Http);
|
||||||
|
httpFactory = injector.get(HttpFactory);
|
||||||
backend = injector.get(MockBackend);
|
backend = injector.get(MockBackend);
|
||||||
baseResponse = new Response('base response');
|
baseResponse = new Response('base response');
|
||||||
sampleObserver = new SpyObserver();
|
sampleObserver = new SpyObserver();
|
||||||
});
|
});
|
||||||
|
|
||||||
afterEach(() => {/*backend.verifyNoPendingRequests();*/});
|
afterEach(() => backend.verifyNoPendingRequests());
|
||||||
|
|
||||||
|
|
||||||
|
describe('HttpFactory', () => {
|
||||||
it('should return an Observable', () => {
|
it('should return an Observable', () => {
|
||||||
expect(typeof http(url).subscribe).toBe('function');
|
expect(typeof httpFactory(url).subscribe).toBe('function');
|
||||||
backend.resolveAllConnections();
|
backend.resolveAllConnections();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -60,7 +71,7 @@ export function main() {
|
||||||
inject([AsyncTestCompleter], (async) => {
|
inject([AsyncTestCompleter], (async) => {
|
||||||
var connection;
|
var connection;
|
||||||
backend.connections.subscribe((c) => connection = c);
|
backend.connections.subscribe((c) => connection = c);
|
||||||
var subscription = http('http://basic.connection')
|
var subscription = httpFactory('http://basic.connection')
|
||||||
.subscribe(res => {
|
.subscribe(res => {
|
||||||
expect(res.text()).toBe('base response');
|
expect(res.text()).toBe('base response');
|
||||||
async.done();
|
async.done();
|
||||||
|
@ -73,7 +84,7 @@ export function main() {
|
||||||
inject([AsyncTestCompleter], async => {
|
inject([AsyncTestCompleter], async => {
|
||||||
var connection;
|
var connection;
|
||||||
backend.connections.subscribe((c) => connection = c);
|
backend.connections.subscribe((c) => connection = c);
|
||||||
http('http://basic.connection', {method: ReadyStates.UNSENT})
|
httpFactory('http://basic.connection', {method: RequestMethods.GET})
|
||||||
.subscribe(res => {
|
.subscribe(res => {
|
||||||
expect(res.text()).toBe('base response');
|
expect(res.text()).toBe('base response');
|
||||||
async.done();
|
async.done();
|
||||||
|
@ -86,7 +97,7 @@ export function main() {
|
||||||
inject([AsyncTestCompleter], async => {
|
inject([AsyncTestCompleter], async => {
|
||||||
var connection;
|
var connection;
|
||||||
backend.connections.subscribe((c) => connection = c);
|
backend.connections.subscribe((c) => connection = c);
|
||||||
http(url, {method: ReadyStates.UNSENT})
|
httpFactory(url, {method: RequestMethods.GET})
|
||||||
.subscribe(res => {
|
.subscribe(res => {
|
||||||
expect(res.text()).toBe('base response');
|
expect(res.text()).toBe('base response');
|
||||||
async.done();
|
async.done();
|
||||||
|
@ -94,4 +105,155 @@ export function main() {
|
||||||
connection.mockRespond(baseResponse)
|
connection.mockRespond(baseResponse)
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('Http', () => {
|
||||||
|
it('should return an Observable', () => {
|
||||||
|
expect(typeof http.request(url).subscribe).toBe('function');
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
it('should perform a get request for given url if only passed a string',
|
||||||
|
inject([AsyncTestCompleter], (async) => {
|
||||||
|
var connection;
|
||||||
|
backend.connections.subscribe((c) => connection = c);
|
||||||
|
var subscription = http.request('http://basic.connection')
|
||||||
|
.subscribe(res => {
|
||||||
|
expect(res.text()).toBe('base response');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
connection.mockRespond(baseResponse)
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should perform a get request for given url if passed a ConnectionConfig instance',
|
||||||
|
inject([AsyncTestCompleter], async => {
|
||||||
|
var connection;
|
||||||
|
backend.connections.subscribe((c) => connection = c);
|
||||||
|
http.request('http://basic.connection', {method: RequestMethods.GET})
|
||||||
|
.subscribe(res => {
|
||||||
|
expect(res.text()).toBe('base response');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
connection.mockRespond(baseResponse);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should perform a get request for given url if passed a dictionary',
|
||||||
|
inject([AsyncTestCompleter], async => {
|
||||||
|
var connection;
|
||||||
|
backend.connections.subscribe((c) => connection = c);
|
||||||
|
http.request(url, {method: RequestMethods.GET})
|
||||||
|
.subscribe(res => {
|
||||||
|
expect(res.text()).toBe('base response');
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
connection.mockRespond(baseResponse);
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
describe('.get()', () => {
|
||||||
|
it('should perform a get request for given url', inject([AsyncTestCompleter], async => {
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.method).toBe(RequestMethods.GET);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.get(url).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('.post()', () => {
|
||||||
|
it('should perform a post request for given url', inject([AsyncTestCompleter], async => {
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.method).toBe(RequestMethods.POST);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.post(url).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
it('should attach the provided body to the request', inject([AsyncTestCompleter], async => {
|
||||||
|
var body = 'this is my put body';
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.text()).toBe(body);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.post(url, body).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('.put()', () => {
|
||||||
|
it('should perform a put request for given url', inject([AsyncTestCompleter], async => {
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.method).toBe(RequestMethods.PUT);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.put(url).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should attach the provided body to the request', inject([AsyncTestCompleter], async => {
|
||||||
|
var body = 'this is my put body';
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.text()).toBe(body);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.put(url, body).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('.delete()', () => {
|
||||||
|
it('should perform a delete request for given url', inject([AsyncTestCompleter], async => {
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.method).toBe(RequestMethods.DELETE);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.delete(url).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('.patch()', () => {
|
||||||
|
it('should perform a patch request for given url', inject([AsyncTestCompleter], async => {
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.method).toBe(RequestMethods.PATCH);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.patch(url).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should attach the provided body to the request', inject([AsyncTestCompleter], async => {
|
||||||
|
var body = 'this is my put body';
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.text()).toBe(body);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.patch(url, body).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe('.head()', () => {
|
||||||
|
it('should perform a head request for given url', inject([AsyncTestCompleter], async => {
|
||||||
|
backend.connections.subscribe((c) => {
|
||||||
|
expect(c.request.method).toBe(RequestMethods.HEAD);
|
||||||
|
backend.resolveAllConnections();
|
||||||
|
async.done();
|
||||||
|
});
|
||||||
|
http.head(url).subscribe(res => {});
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {bootstrap, Component, View, NgFor, NgIf, Inject} from 'angular2/angular2';
|
import {bootstrap, Component, View, NgFor, NgIf, Inject} from 'angular2/angular2';
|
||||||
import {httpInjectables} from 'angular2/http';
|
import {httpInjectables} from 'angular2/http';
|
||||||
import {Http} from 'angular2/src/http/http';
|
import {HttpFactory} from 'angular2/src/http/http';
|
||||||
import {IHttp} from 'angular2/src/http/interfaces';
|
import {IHttp} from 'angular2/src/http/interfaces';
|
||||||
import {Response} from 'angular2/src/http/static_response';
|
import {Response} from 'angular2/src/http/static_response';
|
||||||
import {LocalVariable} from './assign_local_directive';
|
import {LocalVariable} from './assign_local_directive';
|
||||||
|
@ -24,7 +24,7 @@ import {LocalVariable} from './assign_local_directive';
|
||||||
})
|
})
|
||||||
export class HttpCmp {
|
export class HttpCmp {
|
||||||
people: Rx.Observable<Object>;
|
people: Rx.Observable<Object>;
|
||||||
constructor(@Inject(Http) http: IHttp) {
|
constructor(@Inject(HttpFactory) http: IHttp) {
|
||||||
this.people = http('./people.json').map(res => res.json());
|
this.people = http('./people.json').map(res => res.json());
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue