Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support customizing query string in redux-resource-xhr #237

Merged
merged 1 commit into from
Oct 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions docs/extras/redux-resource-xhr.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,46 @@ This is the library used to make HTTP requests. It is a thin wrapper around the
library [`xhr`](https://github.com/naugtur/xhr), and supports all of the same
options and signatures.

On top of that, it adds two features:
On top of that, it adds several new features:

1. Support for a `qs` option (similar to the [`request`](https://github.com/request/request#requestoptions-callback) library).
1. Support for query string serialization (similar to the [`request`](https://github.com/request/request#requestoptions-callback) library).

2. Omitting the callback will return a native
[Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise).

#### Customizing Query String Serialization

If you pass a `qs` object, then the object will be serialized into a query parameter
using the [`querystringify`](https://www.npmjs.com/package/querystringify) library. This
library supports basic serialization, but we don't expect it to work for every API that
you interface with.

You can change how the query string is serialized using two options:

- `qsStringify` - a function with the signature `(qs, options)`. It should return
the string to be appended to the URI.

- `qsStringifyOptions` - an object that is passed as the second argument to the `qsStringify`
method.

For instance, if you wish to use the `qs` library, you might do this:

```js
import { xhr } from 'redux-resource-xhr';
import qs from 'qs';

xhr('/books', {
method: 'GET',
qs: {
pageSize: 10,
pageNumber: 0,
publishers: ['goldenBooks', 'penguinBooks']
},
qsStringify: qs.stringify,
qsStringifyOptions: { arrayFormat: 'brackets' }
}, cb);
```

#### Example

```js
Expand Down
1 change: 1 addition & 0 deletions packages/redux-resource-xhr/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
"babel-register": "^6.24.1",
"cross-env": "^5.0.1",
"in-publish": "^2.0.0",
"qs": "^6.5.1",
"rimraf": "^2.6.1",
"rollup": "^0.45.1",
"rollup-plugin-babel": "^2.7.1",
Expand Down
7 changes: 6 additions & 1 deletion packages/redux-resource-xhr/src/xhr.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,13 @@ import qs from 'querystringify';
// 2. Pass a `qs` option for query string support

function buildUrl(uri, options) {
let qsStringify = options.qsStringify || qs.stringify;
if (options.qs) {
uri += qs.stringify(options.qs, true);
let stringified = qsStringify(options.qs, options.qsStringifyOptions);
if (stringified[0] !== '?') {
stringified = `?${stringified}`;
}
uri += stringified;
}
return uri;
}
Expand Down
25 changes: 25 additions & 0 deletions packages/redux-resource-xhr/test/unit/xhr.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import xhr, {__RewireAPI__} from '../../src/xhr';
import qs from 'qs';

describe('xhr', function() {
afterEach(() => {
Expand Down Expand Up @@ -71,6 +72,30 @@ describe('xhr', function() {
});
});

describe('xhr(url, options, cb); custom query string serializer', () => {
it('should call xhr with the correct args', () => {
this.xhrStub = stub();
__RewireAPI__.__Rewire__('xhr', this.xhrStub);

const cb = stub();
const options = {
method: 'GET',
qs: {a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']]},
qsStringify: qs.stringify,
qsStringifyOptions: {encodeValuesOnly: true}
};
xhr('https://www.google.com', options, cb);

expect(this.xhrStub).to.have.been.calledWith({
uri: 'https://www.google.com?a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h',
method: 'GET',
qs: {a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']]},
qsStringify: qs.stringify,
qsStringifyOptions: {encodeValuesOnly: true}
}, cb);
});
});

describe('xhr(url, cb)', () => {
it('should call xhr with the correct args', () => {
this.xhrStub = stub();
Expand Down