Skip to content

Commit c6fad43

Browse files
committed
feat(fetch): alias fetch response method to type
1 parent 6042ae5 commit c6fad43

File tree

6 files changed

+51
-23
lines changed

6 files changed

+51
-23
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ Query-like object.
6262

6363
`fetch` [options](https://developer.mozilla.org/en-US/docs/Web/API/GlobalFetch/fetch#Parameters).
6464

65-
##### method {string} *Optional*
65+
##### type {string} *Optional*
6666
**Default:** `'json'`
6767

68-
Method to be called on `fetch`'s response.
68+
**Alias:** `method`
69+
70+
Type of reponse data / method to be called on `fetch`'s response (ex: `'json'`, `'text'`, `'blob'`)
6971

7072
##### headers {Object|Headers}
7173

@@ -187,6 +189,7 @@ const resources = {
187189
methods: {
188190
get: ({ id }) => ({ path: id }),
189191
delete: ({ id }) => ({ path: id, options: { method: 'DELETE' } }),
192+
getAsText: ({ id }) => ({ path: id, type: 'text' }),
190193
}
191194
}
192195
}

src/applyMiddleware.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
export default function applyMiddleware(applyTo, middlewares = [], options = {}, params = {}, resourceId = '', method = '') {
1+
export default function applyMiddleware(
2+
applyTo,
3+
middlewares = [],
4+
options = {},
5+
params = {},
6+
resourceId = '',
7+
type = ''
8+
) {
29

310
middlewares = [].concat(middlewares).filter(func => typeof func === 'function');
411

@@ -10,10 +17,10 @@ export default function applyMiddleware(applyTo, middlewares = [], options = {},
1017

1118
const next = index === middlewares.length - 1
1219
? prev.bind(null, params)
13-
: prev.bind(null, options, params, resourceId, method);
20+
: prev.bind(null, options, params, resourceId, type);
1421

1522
return index === 0
16-
? middleware(next)(options, params, resourceId, method)
23+
? middleware(next)(options, params, resourceId, type)
1724
: middleware(next);
1825
}, applyTo);
1926

src/callAPIMethod.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ export default function callAPI(
2020
methodOptions = {}
2121
) {
2222

23-
const { path=[], query={}, options={}, method='json', headers, body } = methodOptions;
23+
const {
24+
path=[],
25+
query={},
26+
options={},
27+
type,
28+
method='json',
29+
headers,
30+
body
31+
} = methodOptions;
2432

2533
const url = formatURL(APINamespace, namespace, path, query);
2634

@@ -33,7 +41,7 @@ export default function callAPI(
3341
if (body) accumulatedFetchOptions.body = body;
3442

3543
return fetch(url, accumulatedFetchOptions)
36-
.then( response => response[method]()
44+
.then( response => response[type || method]()
3745
.catch( () => {
3846
if (!response.ok) throw new APIError(response.status, response.statusText);
3947

test/callAPIMethod.spec.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ test.serial('fetch options', async t => {
105105
},
106106
method: 'text'
107107
};
108-
const spyResponse200 = sinon.spy(Response200, 'text');
108+
const spyResponse200Text = sinon.spy(Response200, 'text');
109109

110110
fetchMock.post(matcher, {});
111111

@@ -118,15 +118,18 @@ test.serial('fetch options', async t => {
118118
method: 'POST',
119119
mode: 'cors'
120120
}, 'correct options');
121-
t.true(spyResponse200.calledOnce);
121+
t.true(spyResponse200Text.calledOnce);
122122

123123
const newMethodOptions = {
124124
...methodOptions,
125+
type: 'json',
125126
headers: new Headers(),
126127
body: 'body'
127128
};
129+
const spyResponse200Json = sinon.spy(Response200, 'json');
128130
await callAPIMethod(APINamespace, fetchOptions, namespace, newMethodOptions);
129131

132+
t.true(spyResponse200Json.calledOnce);
130133
t.deepEqual(fetchMock.lastOptions(matcher), {
131134
cache: 'default',
132135
credentials: 'omit',
@@ -136,7 +139,8 @@ test.serial('fetch options', async t => {
136139
body: newMethodOptions.body
137140
}, 'correct options');
138141

139-
spyResponse200.restore();
142+
spyResponse200Text.restore();
143+
spyResponse200Json.restore();
140144
fetchMock.restore();
141145
});
142146

test/error.spec.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,25 @@ import test from 'ava';
22
import APIError from '../src/error';
33

44
test.beforeEach(t => {
5-
t.context.error = new APIError(404, 'Not Found');
5+
t.context.error = new APIError(404, 'Not Found', { body: 'body'});
66
t.context.errorNoMessage = new APIError(404);
77
});
88

99
test('instance of Error', t => {
10-
t.true(t.context.error instanceof Error)
10+
t.true(t.context.error instanceof Error);
1111
});
1212

1313
test('instance of APIError', t => {
14-
t.true(t.context.error instanceof APIError)
14+
t.true(t.context.error instanceof APIError);
1515
});
1616

1717
test('to string', t => {
1818
t.is(t.context.error.toString(), '404 - Not Found', 'has message');
1919
t.is(t.context.errorNoMessage.toString(), '404', 'No message');
20+
});
21+
22+
test('has correct attributes', t => {
23+
t.is(t.context.error.code, 404);
24+
t.is(t.context.error.message, 'Not Found');
25+
t.deepEqual(t.context.error.body, { body: 'body'});
2026
});

test/shortcuts.spec.js

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,63 +15,63 @@ const dummy = {
1515
path: ['path', 'to', 'resource'],
1616
query: { param: 'value' },
1717
options: { credentials: 'include' },
18-
method: 'text'
18+
type: 'text'
1919
};
2020

2121
test('should set correct HTTP method', t => {
2222
t.deepEqual(GET(dummy), {
2323
path: ['path', 'to', 'resource'],
2424
query: { param: 'value' },
2525
options: { credentials: 'include', method: 'GET' },
26-
method: 'text'
26+
type: 'text'
2727
}, 'GET');
2828
t.deepEqual(HEAD(dummy), {
2929
path: ['path', 'to', 'resource'],
3030
query: { param: 'value' },
3131
options: { credentials: 'include', method: 'HEAD' },
32-
method: 'text'
32+
type: 'text'
3333
}, 'HEAD');
3434
t.deepEqual(POST(dummy), {
3535
path: ['path', 'to', 'resource'],
3636
query: { param: 'value' },
3737
options: { credentials: 'include', method: 'POST' },
38-
method: 'text'
38+
type: 'text'
3939
}, 'POST');
4040
t.deepEqual(PUT(dummy), {
4141
path: ['path', 'to', 'resource'],
4242
query: { param: 'value' },
4343
options: { credentials: 'include', method: 'PUT' },
44-
method: 'text'
44+
type: 'text'
4545
}, 'PUT');
4646
t.deepEqual(DELETE(dummy), {
4747
path: ['path', 'to', 'resource'],
4848
query: { param: 'value' },
4949
options: { credentials: 'include', method: 'DELETE' },
50-
method: 'text'
50+
type: 'text'
5151
}, 'DELETE');
5252
t.deepEqual(CONNECT(dummy), {
5353
path: ['path', 'to', 'resource'],
5454
query: { param: 'value' },
5555
options: { credentials: 'include', method: 'CONNECT' },
56-
method: 'text'
56+
type: 'text'
5757
}, 'CONNECT');
5858
t.deepEqual(OPTIONS(dummy), {
5959
path: ['path', 'to', 'resource'],
6060
query: { param: 'value' },
6161
options: { credentials: 'include', method: 'OPTIONS' },
62-
method: 'text'
62+
type: 'text'
6363
}, 'OPTIONS');
6464
t.deepEqual(TRACE(dummy), {
6565
path: ['path', 'to', 'resource'],
6666
query: { param: 'value' },
6767
options: { credentials: 'include', method: 'TRACE' },
68-
method: 'text'
68+
type: 'text'
6969
}, 'TRACE');
7070
t.deepEqual(PATCH(dummy), {
7171
path: ['path', 'to', 'resource'],
7272
query: { param: 'value' },
7373
options: { credentials: 'include', method: 'PATCH' },
74-
method: 'text'
74+
type: 'text'
7575
}, 'PATCH');
7676
});
7777

0 commit comments

Comments
 (0)