AniUI Academy

Parse a URL query string

mediumDOM & Utilities+250 XPPractice

Filters, pagination and sort order all live in the query string, and reading it back into state is a job you cannot skip. The awkward parts are keys that appear more than once, keys with no value at all, and the fact that a space can arrive as + or as %20.

Implement parseQuery(search) returning a plain object. Strip one leading ? if present, then split the rest on &, ignoring empty segments so "a=1&&b=2&" is fine.

Split each segment on its **first** = only, so a value may itself contain =. A segment with no = is a flag and its value is the empty string "". Decode both key and value by first replacing every + with a space and then calling decodeURIComponent; if decoding throws on a malformed escape, use the raw text instead.

A key seen once maps to a string. A key seen two or more times maps to an array of all of its values, in order of appearance. Empty or missing input returns {}.

Arguments

searchstring
A query string, with or without a leading ?. An empty string returns {}.

Returns

Record<string, string | string[]> — A plain object mapping decoded keys to decoded values. A key that appears more than once maps to an array of its values.

Examples

parseQuery("?page=2&sort=name");
// => { page: "2", sort: "name" }

Simple pairs after an optional leading ?.

parseQuery("tag=a&tag=b&tag=c");
// => { tag: ["a", "b", "c"] }

Repeated keys collect into an array in order.

parseQuery("q=hello+world%20again&empty=&flag");
// => { q: "hello world again", empty: "", flag: "" }

+ and %20 both decode to a space; a bare flag has value "".

What it has to do

  • Strip an optional leading ? and ignore empty & segments.
  • Split each pair on the first = only; a key with no = gets the value "".
  • Decode + as a space as well as percent escapes, on both keys and values.
  • Collect repeated keys into an array in order of appearance, keeping a single occurrence as a string.
  • Return {} for an empty string.

Notes

  • This mirrors the behaviour PHP, Rails and qs all share — a single occurrence stays a string, repeats fold into an array. The browser's URLSearchParams differs: it returns the first via .get() and all via .getAll(), so the output shape is uniform.
  • decodeURIComponent throws on invalid escapes like "%E0%A4"; falling back to the raw text keeps the parser robust against hand-typed URLs.
Asked atGoogleAmazon

Stuck? The javascript course covers everything this challenge needs.

Try it yourself
Loading playground...
5 tests · +250 XP

Discussion

Sign in to post
Sign in to join the conversation.Sign in

No comments yet. Be the first to say something.