Skip to content

Commit 7a77437

Browse files
committed
fix(AjaxObservable): drop resultSelector support in ajax method
closes #1783 BREAKING CHANGE: ajax.*() method no longer support resultSelector, encourage to use `map` instead
1 parent 548ec2a commit 7a77437

File tree

2 files changed

+73
-183
lines changed

2 files changed

+73
-183
lines changed

spec/observables/dom/ajax-spec.ts

Lines changed: 56 additions & 149 deletions
Original file line numberDiff line numberDiff line change
@@ -141,68 +141,6 @@ describe('Observable.ajax', () => {
141141
});
142142
});
143143

144-
it('should have an optional resultSelector', () => {
145-
const expected = 'avast ye swabs!';
146-
let result;
147-
let complete = false;
148-
149-
const obj = {
150-
url: '/flibbertyJibbet',
151-
responseType: 'text',
152-
resultSelector: (res: any) => res.response
153-
};
154-
155-
(<any>Rx.Observable.ajax)(obj)
156-
.subscribe((x: any) => {
157-
result = x;
158-
}, null, () => {
159-
complete = true;
160-
});
161-
162-
expect(MockXMLHttpRequest.mostRecent.url).to.equal('/flibbertyJibbet');
163-
164-
MockXMLHttpRequest.mostRecent.respondWith({
165-
'status': 200,
166-
'contentType': 'application/json',
167-
'responseText': expected
168-
});
169-
170-
expect(result).to.equal(expected);
171-
expect(complete).to.be.true;
172-
});
173-
174-
it('should have error when resultSelector errors', () => {
175-
const expected = 'avast ye swabs!';
176-
let error;
177-
const obj = {
178-
url: '/flibbertyJibbet',
179-
responseType: 'text',
180-
resultSelector: (res: any) => {
181-
throw new Error('ha! ha! fooled you!');
182-
},
183-
method: ''
184-
};
185-
186-
Rx.Observable.ajax(obj)
187-
.subscribe((x: any) => {
188-
throw 'should not next';
189-
}, (err: any) => {
190-
error = err;
191-
}, () => {
192-
throw 'should not complete';
193-
});
194-
195-
expect(MockXMLHttpRequest.mostRecent.url).to.equal('/flibbertyJibbet');
196-
197-
MockXMLHttpRequest.mostRecent.respondWith({
198-
'status': 200,
199-
'contentType': 'application/json',
200-
'responseText': expected
201-
});
202-
203-
expect(error).to.be.an('error', 'ha! ha! fooled you!');
204-
});
205-
206144
it('should error if createXHR throws', () => {
207145
let error;
208146
const obj = {
@@ -213,7 +151,7 @@ describe('Observable.ajax', () => {
213151
}
214152
};
215153

216-
(<any>Rx.Observable.ajax)(obj)
154+
Rx.Observable.ajax(<any>obj)
217155
.subscribe((x: any) => {
218156
throw 'should not next';
219157
}, (err: any) => {
@@ -299,13 +237,13 @@ describe('Observable.ajax', () => {
299237
method: ''
300238
};
301239

302-
Rx.Observable.ajax(obj).subscribe((x: any) => {
303-
throw 'should not next';
304-
}, (err: any) => {
305-
error = err;
306-
}, () => {
307-
throw 'should not complete';
308-
});
240+
Rx.Observable.ajax(obj).subscribe(x => {
241+
throw 'should not next';
242+
}, (err: any) => {
243+
error = err;
244+
}, () => {
245+
throw 'should not complete';
246+
});
309247

310248
expect(MockXMLHttpRequest.mostRecent.url).to.equal('/flibbertyJibbet');
311249

@@ -324,13 +262,13 @@ describe('Observable.ajax', () => {
324262
const expected = JSON.stringify({ foo: 'bar' });
325263

326264
Rx.Observable.ajax('/flibbertyJibbet')
327-
.subscribe((x: any) => {
328-
expect(x.status).to.equal(200);
329-
expect(x.xhr.method).to.equal('GET');
330-
expect(x.xhr.responseText).to.equal(expected);
331-
}, () => {
332-
throw 'should not have been called';
333-
});
265+
.subscribe((x: any) => {
266+
expect(x.status).to.equal(200);
267+
expect(x.xhr.method).to.equal('GET');
268+
expect(x.xhr.responseText).to.equal(expected);
269+
}, () => {
270+
throw 'should not have been called';
271+
});
334272

335273
expect(MockXMLHttpRequest.mostRecent.url).to.equal('/flibbertyJibbet');
336274
MockXMLHttpRequest.mostRecent.respondWith({
@@ -344,15 +282,15 @@ describe('Observable.ajax', () => {
344282
const expected = JSON.stringify({ foo: 'bar' });
345283

346284
Rx.Observable.ajax('/flibbertyJibbet')
347-
.subscribe(() => {
348-
throw 'should not have been called';
349-
}, (x: any) => {
350-
expect(x.status).to.equal(500);
351-
expect(x.xhr.method).to.equal('GET');
352-
expect(x.xhr.responseText).to.equal(expected);
353-
}, () => {
354-
throw 'should not have been called';
355-
});
285+
.subscribe(() => {
286+
throw 'should not have been called';
287+
}, (x: any) => {
288+
expect(x.status).to.equal(500);
289+
expect(x.xhr.method).to.equal('GET');
290+
expect(x.xhr.responseText).to.equal(expected);
291+
}, () => {
292+
throw 'should not have been called';
293+
});
356294

357295
expect(MockXMLHttpRequest.mostRecent.url).to.equal('/flibbertyJibbet');
358296
MockXMLHttpRequest.mostRecent.respondWith({
@@ -367,7 +305,7 @@ describe('Observable.ajax', () => {
367305

368306
beforeEach(() => {
369307
rFormData = root.FormData;
370-
root.FormData = root.FormData || class {};
308+
root.FormData = root.FormData || class { };
371309
});
372310

373311
afterEach(() => {
@@ -468,8 +406,8 @@ describe('Observable.ajax', () => {
468406

469407
Rx.Observable
470408
.ajax.get('/flibbertyJibbet')
471-
.subscribe((x: any) => {
472-
result = x;
409+
.subscribe(x => {
410+
result = x.response;
473411
}, null, () => {
474412
complete = true;
475413
});
@@ -488,70 +426,39 @@ describe('Observable.ajax', () => {
488426
expect(complete).to.be.true;
489427
});
490428

491-
it('should succeed on 200 with a resultSelector', () => {
492-
const expected = { larf: 'hahahahaha' };
493-
let result;
494-
let innerResult;
495-
let complete = false;
496-
497-
Rx.Observable
498-
.ajax.get('/flibbertyJibbet', (x: any) => {
499-
innerResult = x;
500-
return x.response.larf.toUpperCase();
501-
})
502-
.subscribe((x: any) => {
503-
result = x;
504-
}, null , () => {
505-
complete = true;
429+
describe('ajax.post', () => {
430+
it('should succeed on 200', () => {
431+
const expected = { foo: 'bar', hi: 'there you' };
432+
let result: Rx.AjaxResponse;
433+
let complete = false;
434+
435+
Rx.Observable
436+
.ajax.post('/flibbertyJibbet', expected)
437+
.subscribe(x => {
438+
result = x;
439+
}, null, () => {
440+
complete = true;
441+
});
442+
443+
const request = MockXMLHttpRequest.mostRecent;
444+
445+
expect(request.method).to.equal('POST');
446+
expect(request.url).to.equal('/flibbertyJibbet');
447+
expect(request.requestHeaders).to.deep.equal({
448+
'X-Requested-With': 'XMLHttpRequest',
449+
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
506450
});
507451

508-
expect(MockXMLHttpRequest.mostRecent.url).to.equal('/flibbertyJibbet');
509-
510-
MockXMLHttpRequest.mostRecent.respondWith({
511-
'status': 200,
512-
'contentType': 'application/json',
513-
'responseText': JSON.stringify(expected)
514-
});
515-
516-
expect(innerResult.xhr).exist;
517-
expect(innerResult.response).to.deep.equal({ larf: 'hahahahaha' });
518-
expect(result).to.equal('HAHAHAHAHA');
519-
expect(complete).to.be.true;
520-
});
521-
});
522-
523-
describe('ajax.post', () => {
524-
it('should succeed on 200', () => {
525-
const expected = { foo: 'bar', hi: 'there you' };
526-
let result;
527-
let complete = false;
528-
529-
Rx.Observable
530-
.ajax.post('/flibbertyJibbet', expected)
531-
.subscribe((x: any) => {
532-
result = x;
533-
}, null , () => {
534-
complete = true;
452+
request.respondWith({
453+
'status': 200,
454+
'contentType': 'application/json',
455+
'responseText': JSON.stringify(expected)
535456
});
536457

537-
const request = MockXMLHttpRequest.mostRecent;
538-
539-
expect(request.method).to.equal('POST');
540-
expect(request.url).to.equal('/flibbertyJibbet');
541-
expect(request.requestHeaders).to.deep.equal({
542-
'X-Requested-With': 'XMLHttpRequest',
543-
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
544-
});
545-
546-
request.respondWith({
547-
'status': 200,
548-
'contentType': 'application/json',
549-
'responseText': JSON.stringify(expected)
458+
expect(request.data).to.equal('foo=bar&hi=there%20you');
459+
expect(result.response).to.deep.equal(expected);
460+
expect(complete).to.be.true;
550461
});
551-
552-
expect(request.data).to.equal('foo=bar&hi=there%20you');
553-
expect(result.response).to.deep.equal(expected);
554-
expect(complete).to.be.true;
555462
});
556463
});
557-
});
464+
});

src/observable/dom/AjaxObservable.ts

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ export interface AjaxRequest {
1919
withCredentials?: boolean;
2020
createXHR?: () => XMLHttpRequest;
2121
progressSubscriber?: Subscriber<any>;
22-
resultSelector?: <T>(response: AjaxResponse) => T;
2322
responseType?: string;
2423
}
2524

@@ -62,37 +61,32 @@ function getXMLHttpRequest(): XMLHttpRequest {
6261
}
6362

6463
export interface AjaxCreationMethod {
65-
<T>(urlOrRequest: string | AjaxRequest): Observable<T>;
66-
get<T>(url: string, resultSelector?: (response: AjaxResponse) => T, headers?: Object): Observable<T>;
67-
post<T>(url: string, body?: any, headers?: Object): Observable<T>;
68-
put<T>(url: string, body?: any, headers?: Object): Observable<T>;
69-
delete<T>(url: string, headers?: Object): Observable<T>;
64+
(urlOrRequest: string | AjaxRequest): Observable<AjaxResponse>;
65+
get(url: string, headers?: Object): Observable<AjaxResponse>;
66+
post(url: string, body?: any, headers?: Object): Observable<AjaxResponse>;
67+
put(url: string, body?: any, headers?: Object): Observable<AjaxResponse>;
68+
delete(url: string, headers?: Object): Observable<AjaxResponse>;
7069
getJSON<T, R>(url: string, resultSelector?: (data: T) => R, headers?: Object): Observable<R>;
7170
}
7271

73-
function defaultGetResultSelector<T>(response: AjaxResponse): T {
74-
return response.response;
75-
}
76-
77-
export function ajaxGet<T>(url: string, resultSelector: (response: AjaxResponse) => T = defaultGetResultSelector, headers: Object = null) {
78-
return new AjaxObservable<T>({ method: 'GET', url, resultSelector, headers });
72+
export function ajaxGet(url: string, headers: Object = null) {
73+
return new AjaxObservable<AjaxResponse>({ method: 'GET', url, headers });
7974
};
8075

81-
export function ajaxPost<T>(url: string, body?: any, headers?: Object): Observable<T> {
82-
return new AjaxObservable<T>({ method: 'POST', url, body, headers });
76+
export function ajaxPost(url: string, body?: any, headers?: Object): Observable<AjaxResponse> {
77+
return new AjaxObservable<AjaxResponse>({ method: 'POST', url, body, headers });
8378
};
8479

85-
export function ajaxDelete<T>(url: string, headers?: Object): Observable<T> {
86-
return new AjaxObservable<T>({ method: 'DELETE', url, headers });
80+
export function ajaxDelete(url: string, headers?: Object): Observable<AjaxResponse> {
81+
return new AjaxObservable<AjaxResponse>({ method: 'DELETE', url, headers });
8782
};
8883

89-
export function ajaxPut<T>(url: string, body?: any, headers?: Object): Observable<T> {
90-
return new AjaxObservable<T>({ method: 'PUT', url, body, headers });
84+
export function ajaxPut(url: string, body?: any, headers?: Object): Observable<AjaxResponse> {
85+
return new AjaxObservable<AjaxResponse>({ method: 'PUT', url, body, headers });
9186
};
9287

93-
export function ajaxGetJSON<T, R>(url: string, resultSelector?: (data: T) => R, headers?: Object): Observable<R> {
94-
const finalResultSelector = resultSelector ? (res: AjaxResponse) => resultSelector(res.response) : (res: AjaxResponse) => res.response;
95-
return new AjaxObservable<R>({ method: 'GET', url, responseType: 'json', resultSelector: finalResultSelector, headers });
88+
export function ajaxGetJSON<T>(url: string, headers?: Object): Observable<T> {
89+
return new AjaxObservable<AjaxResponse>({ method: 'GET', url, responseType: 'json', headers }).map(x => x.response);
9690
};
9791

9892
/**
@@ -184,7 +178,6 @@ export class AjaxObservable<T> extends Observable<T> {
184178
*/
185179
export class AjaxSubscriber<T> extends Subscriber<Event> {
186180
private xhr: XMLHttpRequest;
187-
private resultSelector: (response: AjaxResponse) => T;
188181
private done: boolean = false;
189182

190183
constructor(destination: Subscriber<T>, public request: AjaxRequest) {
@@ -205,25 +198,15 @@ export class AjaxSubscriber<T> extends Subscriber<Event> {
205198
// properly serialize body
206199
request.body = this.serializeBody(request.body, request.headers['Content-Type']);
207200

208-
this.resultSelector = request.resultSelector;
209201
this.send();
210202
}
211203

212204
next(e: Event): void {
213205
this.done = true;
214-
const { resultSelector, xhr, request, destination } = this;
206+
const { xhr, request, destination } = this;
215207
const response = new AjaxResponse(e, xhr, request);
216208

217-
if (resultSelector) {
218-
const result = tryCatch(resultSelector)(response);
219-
if (result === errorObject) {
220-
this.error(errorObject.e);
221-
} else {
222-
destination.next(result);
223-
}
224-
} else {
225-
destination.next(response);
226-
}
209+
destination.next(response);
227210
}
228211

229212
private send(): XMLHttpRequest {

0 commit comments

Comments
 (0)