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

Function to Serialize JS objects in Query String Parameters #161

Open
ericperez opened this issue Feb 1, 2016 · 9 comments
Open

Function to Serialize JS objects in Query String Parameters #161

ericperez opened this issue Feb 1, 2016 · 9 comments

Comments

@ericperez
Copy link

This is in reference to this line in the code:
o.data = Object.keys(o.data).map(function(key){ return key + "=" + encodeURIComponent(o.data[key]); }).join("&");

I just noticed that there is a very helpful utility function nested in 'fetch' that is not testable and not reusable even though it has pretty generic functionality (serializing objects into Query String params.)

Thoughts on moving this functionality into it's own utility method that is testable and reusable?

Lastly, I can make a pull request if necessary but I would suggest adding encodeURIComponent to the 'key' variable as well because JavaScript allows characters in object keys that need to be encoded in order to be valid query parameter keys. e.g. var params = { "tom & jerry": "friends" };

@LeaVerou
Copy link
Owner

LeaVerou commented Feb 1, 2016

Heh, I've tried to do this so many times. One of them resulted in #136 . All of them however end up not being generic enough, or too big and add bloat that I'm not sure is worth it (to keep Bliss small, we need to exercise a lot of restraint).
You're welcome to try to adapt my PR or come up with your own solution! No promises it will get merged though, even mine didn't :P

@ericperez
Copy link
Author

Thanks for the heads up. I did not see that issue. I think at the minimum just taking the existing functionality and moving it to a place where it's testable and fixing the bug I mentioned above would be an improvement without trying to add new functionality.

@voxpelli
Copy link

voxpelli commented Feb 2, 2016

I guess Lea already knows this, but in relation to this issue it can be interesting to note anyway:

The URL standard, https://url.spec.whatwg.org/, actually has a Query String builder in the form of URLSearchParams (see MDN docs) that while it doesn't provide a plain object to URLSearchParams converter can be used to set key/value pairs and have them be converted to a query string:

o.data = Object.keys(o.data).reduce(function (params, key) {
  params.set(key, o.data[key]);
  return params;
}, new URLSearchParams()).toString();

The URL standard sort of feels like the GET counterpart of the POST forms' FormData standard.

As Bless is about vanilla js it could perhaps be interesting to try and use suchna standard if one wants to make something like this more generic. That will also show possible short-comings in the standard which one can eg. propose extensions to fix where suitable – such as maybe a way to send in such a plain object directly into URLSearchParams as a setter counterpart to the existing .entries().

Not sure how if Bliss is generally positive or negative towards relying on polyfilling – it can surely make Bliss less small. If one would want to try and use more of the URL standard going forward then there seems to be polyfills like https://github.com/WebReflection/url-search-params out there anyway that one can use until non-Firefox browsers catches up on that spec part.

Update: There's actually already an issue about this in the URL-spec repo: whatwg/url#27
Update 2: And now I realize that at the same time as writing this comment the Chrome team decided to finally release support for this and blog about it – great timing I guess: https://developers.google.com/web/updates/2016/01/urlsearchparams

@LeaVerou
Copy link
Owner

LeaVerou commented Feb 4, 2016

I've looked into URLSearchParams, no idea why I decided against using them there.
Support is not an issue, as we suggest using bliss along with polyfill.io.
I should look at them again.

@friday
Copy link
Contributor

friday commented Oct 25, 2017

URLSearchParams is useful if you want to manipulate a query string (probably intended for usage pushState and similar), but not as much if you want to build them from scratch from object literals. set only takes strings, so if you pass objects, arrays or other URLSearchParams it will convert them to strings ("[Object object]"). So it won't work with nested data structures, and for objects that aren't nested something like this is easier:

Object.entries(data).map(pair => pair.map(encodeURIComponent).join('=')).join('&')

@friday
Copy link
Contributor

friday commented Nov 20, 2017

I just posted an alternative suggestion (json) to this problem: #213

@Chieftl
Copy link

Chieftl commented Jun 5, 2018

You can try to use q-flat package
It makes objects flat like this:

{
  "page": {
    "limit": 10,
    "offset": 55
  },
  "filter": {
    "year": {
      "gt": 2000
    }
  },
  "scalar": 3.1415,
  "categories": [
    1057
  ]
}

will be convert to

{
  "page[limit]": 10,
  "page[offset]": 55,
  "filter[year][gt]": 2000,
  "scalar": 3.1415,
  "categories[0]": 1057
}

More details:
sindresorhus/query-string#147 (comment)

@friday
Copy link
Contributor

friday commented Jun 5, 2018

You probably shouldn't use query strings for that ^. All your numbers will be converted to strings. See #213.

@Chieftl
Copy link

Chieftl commented Jun 5, 2018

@friday well, I don't use query-string for that, I use that for query-string :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants