parent
93596dff3f
commit
b68e561c0f
|
@ -2,10 +2,14 @@ import {bind, Binding} from 'angular2/di';
|
|||
import {Http, HttpFactory} from './src/http/http';
|
||||
import {XHRBackend} from 'angular2/src/http/backends/xhr_backend';
|
||||
import {BrowserXHR} from 'angular2/src/http/backends/browser_xhr';
|
||||
import {BaseRequestOptions} from 'angular2/src/http/base_request_options';
|
||||
|
||||
export {Http};
|
||||
export var httpInjectables: List<any> = [
|
||||
bind(BrowserXHR)
|
||||
.toValue(BrowserXHR),
|
||||
XHRBackend,
|
||||
bind(BrowserXHR).toValue(BrowserXHR),
|
||||
bind(Http).toFactory(HttpFactory, [XHRBackend])
|
||||
BaseRequestOptions,
|
||||
bind(HttpFactory).toFactory(HttpFactory, [XHRBackend, BaseRequestOptions]),
|
||||
Http
|
||||
];
|
||||
|
|
|
@ -6,10 +6,10 @@ import {RequestOptions} from './interfaces';
|
|||
import {Injectable} from 'angular2/di';
|
||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||
|
||||
export class RequestOptionsClass {
|
||||
export class RequestOptionsClass implements RequestOptions {
|
||||
method: RequestMethods = RequestMethods.GET;
|
||||
headers: Headers;
|
||||
body: URLSearchParams | FormData | string;
|
||||
body: URLSearchParams | FormData | Blob | string;
|
||||
mode: RequestModesOpts = RequestModesOpts.Cors;
|
||||
credentials: RequestCredentialsOpts;
|
||||
cache: RequestCacheOpts;
|
||||
|
|
|
@ -5,7 +5,7 @@ export enum RequestCacheOpts {Default, NoStore, Reload, NoCache, ForceCache, Onl
|
|||
|
||||
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};
|
||||
|
||||
|
|
|
@ -6,6 +6,8 @@ import {Request} from './static_request';
|
|||
import {Response} from './static_response';
|
||||
import {XHRBackend} from './backends/xhr_backend';
|
||||
import {BaseRequestOptions} from './base_request_options';
|
||||
import {RequestMethods} from './enums';
|
||||
import {URLSearchParams} from './url_search_params';
|
||||
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
|
||||
@Injectable()
|
||||
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;
|
||||
|
@ -56,13 +108,6 @@ if (Rx.hasOwnProperty('default')) {
|
|||
}
|
||||
export function HttpFactory(backend: XHRBackend, defaultOptions: BaseRequestOptions) {
|
||||
return function(url: string, options?: RequestOptions) {
|
||||
return <Rx.Observable<Response>>(Observable.create(observer => {
|
||||
var connection: Connection = backend.createConnection(new Request(url, options));
|
||||
var internalSubscription = connection.response.subscribe(observer);
|
||||
return () => {
|
||||
internalSubscription.dispose();
|
||||
connection.dispose();
|
||||
}
|
||||
}))
|
||||
return httpRequest(backend, new Request(url, defaultOptions.merge(options)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import {URLSearchParams} from './url_search_params';
|
|||
export interface RequestOptions {
|
||||
method?: RequestMethods;
|
||||
headers?: Headers;
|
||||
body?: URLSearchParams | FormData | string;
|
||||
body?: URLSearchParams | FormData | Blob | string;
|
||||
mode?: RequestModesOpts;
|
||||
credentials?: RequestCredentialsOpts;
|
||||
cache?: RequestCacheOpts;
|
||||
|
|
|
@ -24,8 +24,8 @@ export function main() {
|
|||
it('should retain previously merged values when merging again', () => {
|
||||
var options1 = new BaseRequestOptions();
|
||||
var options2 = options1.merge({method: RequestMethods.DELETE});
|
||||
var options3 = options2.merge({mode: RequestModesOpts.NoCors}) expect(options3.mode)
|
||||
.toBe(RequestModesOpts.NoCors);
|
||||
var options3 = options2.merge({mode: RequestModesOpts.NoCors});
|
||||
expect(options3.mode).toBe(RequestModesOpts.NoCors);
|
||||
expect(options3.method).toBe(RequestMethods.DELETE);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,11 +12,11 @@ import {
|
|||
} from 'angular2/test_lib';
|
||||
import {Http, HttpFactory} from 'angular2/src/http/http';
|
||||
import {XHRBackend} from 'angular2/src/http/backends/xhr_backend';
|
||||
import {httpInjectables} from 'angular2/http';
|
||||
import {Injector, bind} from 'angular2/di';
|
||||
import {MockBackend} from 'angular2/src/http/backends/mock_backend';
|
||||
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 {
|
||||
onNext: Function;
|
||||
|
@ -38,20 +38,31 @@ export function main() {
|
|||
var backend: MockBackend;
|
||||
var baseResponse;
|
||||
var sampleObserver;
|
||||
var httpFactory;
|
||||
beforeEach(() => {
|
||||
injector = Injector.resolveAndCreate(
|
||||
[MockBackend, bind(Http).toFactory(HttpFactory, [MockBackend])]);
|
||||
injector = Injector.resolveAndCreate([
|
||||
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);
|
||||
httpFactory = injector.get(HttpFactory);
|
||||
backend = injector.get(MockBackend);
|
||||
baseResponse = new Response('base response');
|
||||
sampleObserver = new SpyObserver();
|
||||
});
|
||||
|
||||
afterEach(() => {/*backend.verifyNoPendingRequests();*/});
|
||||
|
||||
afterEach(() => backend.verifyNoPendingRequests());
|
||||
|
||||
describe('HttpFactory', () => {
|
||||
it('should return an Observable', () => {
|
||||
expect(typeof http(url).subscribe).toBe('function');
|
||||
expect(typeof httpFactory(url).subscribe).toBe('function');
|
||||
backend.resolveAllConnections();
|
||||
});
|
||||
|
||||
|
@ -60,7 +71,7 @@ export function main() {
|
|||
inject([AsyncTestCompleter], (async) => {
|
||||
var connection;
|
||||
backend.connections.subscribe((c) => connection = c);
|
||||
var subscription = http('http://basic.connection')
|
||||
var subscription = httpFactory('http://basic.connection')
|
||||
.subscribe(res => {
|
||||
expect(res.text()).toBe('base response');
|
||||
async.done();
|
||||
|
@ -73,7 +84,7 @@ export function main() {
|
|||
inject([AsyncTestCompleter], async => {
|
||||
var connection;
|
||||
backend.connections.subscribe((c) => connection = c);
|
||||
http('http://basic.connection', {method: ReadyStates.UNSENT})
|
||||
httpFactory('http://basic.connection', {method: RequestMethods.GET})
|
||||
.subscribe(res => {
|
||||
expect(res.text()).toBe('base response');
|
||||
async.done();
|
||||
|
@ -86,7 +97,7 @@ export function main() {
|
|||
inject([AsyncTestCompleter], async => {
|
||||
var connection;
|
||||
backend.connections.subscribe((c) => connection = c);
|
||||
http(url, {method: ReadyStates.UNSENT})
|
||||
httpFactory(url, {method: RequestMethods.GET})
|
||||
.subscribe(res => {
|
||||
expect(res.text()).toBe('base response');
|
||||
async.done();
|
||||
|
@ -94,4 +105,155 @@ export function main() {
|
|||
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 {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 {Response} from 'angular2/src/http/static_response';
|
||||
import {LocalVariable} from './assign_local_directive';
|
||||
|
@ -24,7 +24,7 @@ import {LocalVariable} from './assign_local_directive';
|
|||
})
|
||||
export class HttpCmp {
|
||||
people: Rx.Observable<Object>;
|
||||
constructor(@Inject(Http) http: IHttp) {
|
||||
constructor(@Inject(HttpFactory) http: IHttp) {
|
||||
this.people = http('./people.json').map(res => res.json());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue