Skip to content

Instantly share code, notes, and snippets.

@joshnuss
Last active August 19, 2019 22:34
Show Gist options
  • Save joshnuss/5e7632bc4f37b062b7f1 to your computer and use it in GitHub Desktop.
Save joshnuss/5e7632bc4f37b062b7f1 to your computer and use it in GitHub Desktop.
Parse & Generate query strings with Coffeescript

Parse & Generate Complex Query Strings

with Coffeescript

This code will allow you to build a JS dict/object from a query string. It supports arrays, dicts and scalars (strings)

For example, this string:

>> query = "arr[]=1&arr[]=2&q=foo&f=baz&h[a]=1&h[bc]=3"
>> queryString.parse(query)

would be parsed into an object like this:

{ arr: [ '1', '2' ], q: 'foo', f: 'baz', h: { a: '1', bc: '3' } }

You can then serialize the dict back into a query string using the the generate() function

>> o = { arr: [ '1', '2' ], q: 'foo', f: 'baz', h: { a: '1', bc: '3' } }
>> queryString.generate(o)
"arr[]=1&arr[]=2&q=foo&f=baz&h[a]=1&h[bc]=3"
queryString =
parse: (uri) ->
queryString = {}
addArrayValue = (key, value) ->
(queryString[key] ||= []).push(value)
addDictValue = (name, key, value) ->
(queryString[name] ||= {})[key] = value
addValue = (key, value) ->
match = key.match(/^([^\[]+)(\[(.*)\])$/i)
if match
if match[3]
addDictValue(match[1], match[3], value)
else
addArrayValue(match[1], value)
else
queryString[key] = value
uri.replace new RegExp("([^?=&]+)(=([^&]*))?", "g"), (_, key, _, value) -> addValue(key, value)
queryString
generate: (obj) ->
parts = []
for key, value of obj
if Array.isArray(value)
parts.push("#{key}[]=#{v}") for v in value
else if typeof(value) == 'object'
for k, v of value
parts.push("#{key}[#{k}]=#{v}")
else
parts.push("#{key}=#{value}")
parts.join("&")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment