-
Notifications
You must be signed in to change notification settings - Fork 96
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
Add support for options.qs #160
Conversation
README.md
Outdated
### `options.qs` | ||
|
||
A value to be transformed into a query string. This library does not provide | ||
a parser for `options.qs` out of the box: you must define it yourself as |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a parser. I would call it a query string builder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch.
index.js
Outdated
var qsStringifyDefined = isFunction(createXHR.queryStringStringify); | ||
|
||
if (options.qs && !qsStringifyDefined) { | ||
throw new Error("You passed a 'qs' option, but did not define an 'xhr.queryStringStringify' function.\nYou must either omit the 'qs' option, or define 'xhr.queryStringStringify'.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll shorten this message if you don't mind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem. Go for it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
my only nit is about term queryStringStringify
. When we're talking about uri encoding it doesn't serve developers to use the same terms as JSON operations. Regardless of what popular libs do, uri encoding looks very different from JSON
README.md
Outdated
|
||
A value to be transformed into a query string. This library does not provide | ||
a parser for `options.qs` out of the box: you must define it yourself as | ||
`xhr.queryStringStringify`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we call this xhr.qs
?
README.md
Outdated
a parser for `options.qs` out of the box: you must define it yourself as | ||
`xhr.queryStringStringify`. | ||
|
||
If `options.qs` is defined, and `xhr.queryStringStringify` is not, then an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xhr.qs
please
README.md
Outdated
assumptions about how to handle them, and does not support the `qs` option out | ||
of the box. | ||
|
||
To support the `qs` option, you must define an `xhr.queryStringStringify` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another xhr.qs
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls also remove you must
, it reads better as:
"To support a qs
option, define an xhr...
function"
README.md
Outdated
and returns a string that is appended to the URL. | ||
|
||
You do not need to include a leading "?" in the value that you return from | ||
`xhr.queryStringStringify`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment
README.md
Outdated
var xhr = require('xhr') | ||
var qs = require('qs') | ||
|
||
xhr.queryStringStringify = qs.stringify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
xhr.qs = qs.stringify
index.js
Outdated
@@ -7,6 +7,7 @@ var xtend = require("xtend") | |||
module.exports = createXHR | |||
createXHR.XMLHttpRequest = window.XMLHttpRequest || noop | |||
createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window.XDomainRequest | |||
createXHR.queryStringStringify = null // Define this as a function to support the `qs` option |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createXHR.qs = null
index.js
Outdated
throw new Error("You passed a 'qs' option, but did not define an 'xhr.queryStringStringify' function.\nYou must either omit the 'qs' option, or define 'xhr.queryStringStringify'.") | ||
} | ||
|
||
var qs = options.qs && qsStringifyDefined ? '?' + createXHR.queryStringStringify(options.qs) : ''; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same comment
@@ -60,6 +60,7 @@ type XhrOptions = String | { | |||
withCredentials: Boolean?, | |||
responseType: String?, | |||
beforeSend: Function? | |||
qs: Any? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
keep consistent w/ readme and avoid confusion of a non-type, i.e. qs: Function?
here
To support the
qs
option, you must define anxhr.queryStringStringify
function. This function accepts the value ofoptions.qs
as its first argument, and returns a string that is appended to the URL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I disagree here, the type of qs
is unknown until you specify the xhr.queryStringStringify
or xhr.qs
function.
You can specify a function accepting an array or an object or a specific structure or a Map...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll leave it as-is for now. Y'all can hash this out in the v3 branch post-merge?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
README.md
Outdated
assumptions about how to handle them, and does not support the `qs` option out | ||
of the box. | ||
|
||
To support the `qs` option, you must define an `xhr.queryStringStringify` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls also remove you must
, it reads better as:
"To support a qs
option, define an xhr...
function"
@reqshark , i'm surprised you so strongly associate the word "stringify" with JSON. We don't have to use the term, but I think it is the best decision. I don't these other libs have made a mistake using it. Anything can be "stringified" – it's basically just a synonym for serializing, right? Either way, I think using "qs" as both the option you pass when building an xhr, and as the builder/stringifier, could potentially cause confusion. Users have to deal with learning that "the xhr.qs function accepts options.qs and returns it as string." Not as straightforward as it could be imo. How would you feel about any of these alternatives:
Another verb you used was "encode," but this function is not encoding anything imo, so i don't think we should consider that option. Thanks for the review, you two! Feel free to push directly to this branch; otherwise, I'll update based on your comment tomorrow. |
ok fair points @jmeas, what about |
the when forming XHR requests browser's the fact that you don't think "this function is encoding anything" gets precisely to my point about JSON terminology confusing people |
I'd support naming things is hard. :) |
I'll name it Would you like me to add tests in addition to these other changes you requested? Also, I made all of the suggested changes in the fixup PR (I think). Let me know if I missed anything. I'll squash the commits when you give this PR your final 👍 |
var xhr = require('xhr') | ||
var qs = require('qs') | ||
|
||
xhr.qsSerialize = qs.stringify |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
^ this line is very convincing towards naming it qsStringify after all.
I'll keep thinking about it after I merge this PR into v3 branch
var qsStringifyDefined = isFunction(createXHR.qsSerialize); | ||
|
||
if (options.qs && !qsStringifyDefined) { | ||
throw new Error("To use the 'qs' option, first define an 'xhr.qsSerialize' function.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great, I don't have to redact it anymore - exactly what I wanted to do.
I'm merging this manually to |
Closing as this is merged into v3development: 807745f |
Sorry I'm late to the party. To align with Node, qs, query-string, and request, the function reference should be qsStringify. That's the nomenclature. And aside from some creative edge cases, options.qs should be an Object, as it is in request. Looking at the bigger picture, do we want to keep extending the API surface on the createXhr object? That moves us further away from a guiding factor in the simplicity of request: all configuration goes in that In a comment on #159, @jmeas makes a point that it's "a hard sell to use this lib for universal code, as the Node code would absolutely use the qs option." It's worth considering how committed we are to the "subset of request" goal. We could stay fully within the request API by pulling in qs as a dependency, but that obviously adds bloat that many may not need. The qsStringify function could instead be set on var req = xhr.defaults(function (options, callback) {
options.uri = (options.uri || options.url) + '?' + qs.stringify(options.qs);
return xhr(options, callback);
}); |
Valid points. Would you mind starting a new issue with this and tagging v3 milestone? |
@gsf, all of that sounds 👌 to me. Does the |
Issue #163 created. And yes, in that example, the req function would be used for all future calls, just like a full wrapper. |
Just a quick proof-of-concept implementation of #159.