How to get a map of key-value pairs out of the query string of a url? We want to avoid string wrangling for what is surely a very common use-case. If the given way is utilizing a tiny JS function/lib and then converting it to a ClojureScript map, that’s fine. Example:
To add to the answers above - note that a query string can have multiple parameters with the same name. A naive “mappification” will ignore all but one.
A query string has no behavior. But the way to interpret repeating parameter names is up to the implementation. More than that - the whole query string doesn’t have a standardized format. I’m too lazy to look through the relevant RFCs, but this is what Wikipedia says:
The exact structure of the query string is not standardized. Methods used to parse the query string may differ between websites.
URLSearchParams.forEach will iterate across all values:
function arrayify(x){
return Array.isArray(x) ? x : ((null == x) ? [] : [x]);
}
let out = {};
new URL("https://x.site?a=1&b=2&b=3").searchParams.forEach(function (v,k){
let curr = out[k];
if(curr){
let next = arrayify(curr);
next.push(v);
out[k] = next;
}
else{
out[k] = v;
}
});
console.log(out);
=> {"a": "1", "b": ["2", "3"]}
This uses only String.split, overwriting duplicate keys.
function params_from_url(url){
let arr = url.split("?");
let search = arr[1];
let params = {};
if(search){
for(let pair of search.split("&")){
let [key,val] = pair.split("=");
params[key] = val;
};
}
return params;
}
params_from_url("https://x.site?a=1&b=2&b=3"
=> {a: "1", b: "3"}
this function can be readily converted an a reduce call for creating clj datastructures, optionally adding in the logic if single key/multiple values are needed.
Nice. Array.from is so much simple than using forEach. It’s great that URLSearchParams supports iteration as both an array and object. The class also does auto URLDecoding (which won’t with my example).
Also… this probably show how long I haven’t been using cljs… but when did map and reduce start working with native arrays?
I guess each implementation has their benefits, ie
lambda island is jvm/js compatible
URLSearchParams is simplest for js
String.split solution can be ported/transpiled pretty easily to other langs such as lua/python